华为云用户手册
-
参数说明 表1 参数说明 参数 是否必选 默认值 数据类型 参数说明 spark.hadoop.fs.obs.bucket.USER_BUCKET_NAME.dew.access.key 是 无 String 其中USER_BUCKET_NAME为用户的桶名,需要进行替换为用户的使用的OBS桶名。 参数的值为用户定义在 CS MS通用凭证中的键key, 其Key对应的value为用户的AK(Access Key Id),需要具备访问OBS对应桶的权限。 spark.hadoop.fs.obs.bucket.USER_BUCKET_NAME.dew.secret.key 是 无 String 其中USER_BUCKET_NAME为用户的桶名,需要进行替换为用户的使用的OBS桶名。 参数的值为用户定义在C SMS 通用凭证中的键key, 其Key对应的value为用户的SK(Secret Access Key),需要具备访问OBS对应桶的权限。 spark.hadoop.fs.obs.security.provider 是 无 String OBS AKSK认证机制,使用DEW服务中的CSMS凭证管理,获取OBS的AK、SK。 默认取值为com.dli.provider.UserObsBasicCredentialProvider spark.hadoop.fs.dew.csms.secretName 是 无 String 在DEW服务的凭据管理中新建的通用凭据的名称。 配置示例:spark.hadoop.fs.dew.csms.secretName=secretInfo spark.hadoop.fs.dew.endpoint 是 无 String 指定要使用的DEW服务所在的endpoint信息。 获取地区和终端节点。 配置示例:spark.hadoop.fs.dew.endpoint=kms.cn-xxxx.myhuaweicloud.com spark.hadoop.fs.dew.csms.version 否 最新的version String 在DEW服务的凭据管理中新建的通用凭据的版本号(凭据的版本标识符)。 若不指定,则默认获取该通用凭证的最新版本号。 配置示例: spark.hadoop.fs.dew.csms.version=v1 spark.hadoop.fs.dew.csms.cache.time.second 否 3600 Long Spark作业访问获取CSMS通用凭证后,缓存的时间。 单位为秒。默认值为3600秒。 spark.hadoop.fs.dew.projectId 否 有 String DEW所在的项目ID, 默认是Spark作业所在的项目ID。 获取项目ID spark.dli.job.agency.name 是 - String 自定义委托名称。
-
前提条件 已在DEW服务创建通用凭证,并存入凭据值。具体操作请参考:创建通用凭据。 已创建 DLI 访问DEW的委托并完成委托授权。该委托需具备以下权限: DEW中的查询凭据的版本与凭据值ShowSecretVersion接口权限,csms:secretVersion:get。 DEW中的查询凭据的版本列表ListSecretVersions接口权限,csms:secretVersion:list。 DEW解密凭据的权限,kms:dek:decrypt。 委托权限示例请参考自定义DLI委托权限和常见场景的委托权限策略。 仅支持Spark3.3.1(Spark通用队列场景)及以上版本使用DEW管理访问凭据,在创建作业时,请配置作业使用Spark3.3.1版本、且已在作业中配置允许DLI访问DEW的委托信息。 自定义委托及配置请参考自定义DLI委托权限。 使用该功能,所有涉及OBS的桶,都需要进行配置AKSK。
-
语法格式 在Spark Jar作业编辑界面,选择配置优化参数,配置信息如下: 不同的OBS桶,使用不同的AKSK认证信息。 可以使用如下配置方式,根据桶指定不同的AKSK信息,参数说明详见表1。 spark.hadoop.fs.obs.bucket.USER_BUCKET_NAME.dew.access.key= USER_AK_CSMS_KEY spark.hadoop.fs.obs.bucket.USER_BUCKET_NAME.dew.secret.key= USER_SK_CSMS_KEY spark.hadoop.fs.obs.security.provider = com.dli.provider.UserObsBasicCredentialProvider spark.hadoop.fs.dew.csms.secretName= CredentialName spark.hadoop.fs.dew.endpoint=ENDPOINT spark.hadoop.fs.dew.csms.version=VERSION_ID spark.hadoop.fs.dew.csms.cache.time.second =CACHE_TIME spark.dli.job.agency.name=USER_AGENCY_NAME
-
操作场景 DLI将Spark Jar作业并的输出数据写入到OBS时,需要配置AKSK访问OBS,为了确保AKSK数据安全,您可以用过 数据加密 服务(Data Encryption Workshop,DEW)、云凭据管理服务(Cloud Secret Management Service,CSMS),对AKSK统一管理,有效避免程序硬编码或明文配置等问题导致的敏感信息泄露以及权限失控带来的业务风险。 本例以获取访问OBS的AKSK为例介绍Spark Jar使用DEW获取访问凭证读写OBS的操作指导。
-
解决方案 为了解决因IP地址不足导致的Flink作业提交失败问题,可以在作业优化参数中添加以下配置: 启用 HostNetwork。 kubernetes.dli.hostnetwork.enabled=true kubernetes.hostnetwork.enabled=true 调整Leader Election 配置: high-availability.kubernetes.leader-election.renew-deadline=15s high-availability.kubernetes.leader-election.lease-duration=15s
-
入门实践 我们整理了从队列网络连通、不同类型的作业分析、数据迁移场景的常用开发指南和最佳实践内容,帮助您更好的使用DLI进行大数据分析和处理。 表1 DLI常用开发指南与最佳实践 场景 操作指导 描述 队列网络连通 配置DLI队列与内网数据源的网络连通 DLI在创建运行作业需要连接外部其他数据源,本节操作介绍队列与外部数据源之间的网络连通方法,如:DLI连接 MRS 、RDS、 CSS 、Kafka、DWS时,需要打通DLI和外部数据源之间的网络。 配置DLI 队列与公网网络连通 介绍DLI队列在公网访问场景下网络连通的方法。通过配置SNAT规则,添加到公网的路由信息,可以实现队列到和公网的网络打通。 Spark SQL作业开发 使用Spark SQL作业分析OBS数据 介绍使用Spark SQL作业创建OBS表、导入OBS表数据、插入和查询OBS表数据等操作。 Flink OpenSource SQL作业开发 从Kafka读取数据写入到RDS 介绍使用Flink OpenSource SQL作业从Kafka读取数据写入到RDS的开发示例。 从Kafka读取数据写入到DWS 介绍使用Flink OpenSource SQL作业从Kafka读取数据写入到DWS的开发示例。 从Kafka读取数据写入到Elasticsearch 介绍使用Flink OpenSource SQL作业从Kafka读取数据写入到Elasticsearch的开发示例。 从MySQL CDC源表读取数据写入到DWS 介绍使用Flink OpenSource SQL作业从MySQL CDC源表读取数据写入到DWS的开发示例。 从PostgreSQL CDC源表读取数据写入到DWS 介绍使用Flink OpenSource SQL作业从PostgreSQL CDC源表读取数据写入到DWS的开发示例。 Flink Jar作业开发 Flink Jar作业开发基础样例 通过自定义作业与MRS进行交互为例进行介绍Flink Jar作业开发样例。 使用Flink Jar写入数据到OBS开发指南 介绍将kafka数据处理后写入到OBS的操作样例。 使用Flink Jar连接开启SASL_SSL认证的Kafka 介绍使用Flink OpenSource SQL连接开启SASL_SSL认证的Kafka。 使用Flink Jar读写DIS开发指南 介绍Flink Jar作业读写DIS数据的操作方法。 Spark Jar作业开发 使用Spark Jar作业读取和查询OBS数据 介绍从编写Spark程序代码读取和查询OBS数据、编译打包到提交Spark Jar作业的开发样例。 数据迁移 迁移Hive数据至DLI 介绍如何通过 CDM 数据同步功能,迁移MRS Hive数据至DLI。 迁移Kafka数据至DLI 介绍如何通过CDM数据同步功能,迁移MRS Kafka数据至DLI。 迁移Elasticsearch数据至DLI 介绍如何通过CDM数据同步功能,迁移Elasticsearch类型的CSS集群数据至DLI。 迁移RDS数据至DLI 介绍如何通过CDM数据同步功能,迁移关系型数据库RDS数据至DLI。 迁移DWS数据至DLI 介绍如何通过CDM数据同步功能,迁移 数据仓库 服务DWS数据至DLI。
-
后续指引 完成增强型跨源连接访问RDS快速入门操作后,如果您想了解更多关于跨源连接的相关操作,建议您参考以下指引阅读。 分类 文档 说明 界面操作 跨源连接和跨源分析 提供跨源连接、分析相关的功能介绍和操作指导。 开发指南 跨源访问其他数据源 提供跨源访问CSS、DWS、HBase、OpenTSDB、RDS、Redis、Mongo等样例代码和开发指导。 增强型跨源API参考 提供增强型跨源相关API接口指导。
-
步骤6:提交SQL作业 本节示例以SQL作业为例说明如何跨源访问RDS表。 在DLI管理控制台的左侧导航栏中,单击“SQL编辑器”,进入SQL作业编辑器页面。 在“SQL编辑器”页面右侧的编辑窗口中,输入如下SQL语句创建数据库db1,单击“执行”。 create database db1; 在编辑窗口中,选择队列“dli_queue_01”和数据库“db1”。输入如下SQL语句创建表,向RDS表插入数据,以及查询数据,单击“执行”。 根据界面显示的执行结果查询RDS表数据信息,整个操作完成。 CREATE TABLE IF NOT EXISTS rds_test USING JDBC OPTIONS ( 'url' = 'jdbc:mysql://{{ip}}:{{port}}', //RDS内网地址及端口 'driver' = 'com.mysql.jdbc.Driver', 'dbtable' = 'dli_demo.tabletest', //在RDS创建的库名及表名 'passwdauth'="xxxxx" // DLI侧创建的Password类型的跨源认证名称。使用跨源认证则无需在作业中配置账号和密码。 ) insert into rds_test VALUES ('123','abc'); SELECT * from rds_test;
-
步骤2:创建RDS数据库表 登录RDS管理控制台。 在管理控制台左上角选择区域和项目。 在“实例管理页面”,找到您已经创建的RDS实例,记录并保存RDS实例的内网地址。 图2 内网地址 单击所创建RDS实例的“登录”,跳转至“数据管理服务-DAS”。输入相关账户信息,单击“测试连接”。显示连接成功后,单击“登录”,进入“实例登录”页面。 图3 登录RDS 图4 实例登录 登录RDS实例后,单击“新建数据库”,创建名称为“dli_demo”的数据库。 单击“SQL查询”,执行如下SQL创建表。 CREATE TABLE `dli_demo`.`tabletest` ( `id` VARCHAR(32) NOT NULL, `name` VARCHAR(32) NOT NULL, PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4;
-
操作流程 使用DLI提交SQL作业查询RDS MySQL数据操作流程如表1所示。 开始进行如下操作前,请务必参考准备工作完成必要操作。 表1 使用DLI提交SQL作业查询RDS MySQL数据的操作流程 操作步骤 说明 步骤1:创建RDS MySQ L实例 样例场景需要创建RDS MySQL实例。 步骤2:创建RDS数据库表 登录RDS实例创建数据库和表。 步骤3:创建弹性资源池并添加队列 创建提交作业所需的计算资源。 步骤4:创建增强型跨源连接 通过增强型跨源连接建立DLI弹性资源池与RDS实例的网络连通。 步骤5:创建跨源认证 使用跨源认证保存DLI读写RDS数据的访问凭证。 步骤6:提交SQL作业 使用标准SQL语句进行数据的查询和分析。
-
步骤1:创建RDS MySQL实例 本样例中,假设作业名称为“JobSample”,采用RDS服务作为数据源,创建RDS MySQL实例,具体操作请参见《 云数据库MySQL 快速入门》中的“MySQL快速入门”章节。 登录RDS管理控制台。 在管理控制台左上角选择区域和项目。 在“实例管理”页面,单击“购买数据库实例”。 在购买数据库实例页面,选择计费模式,填写并选择实例相关信息后,单击“立即购买”。 根据业务规划配置参数信息,本例参数配置信息如所示。 更多RDS实例的参数配置信息请参考购买RDS实例。 表2 RDS MySQL实例参数配置信息 参数名称 参数说明 取值样例 计费模式 选择RDS实例的计费模式。 按需计费 区域 资源所在的区域。 华东-上海二 实例名称 实例名称。 rds-demo 数据库引擎 MySQL MySQL 数据库版本 选用RDS for MySQL数据库时,请根据实际业务需求选择合适的数据库引擎版本。建议您选择当前可用的最高版本数据库,因其性能更稳定,安全性更高,使用更可靠。 8.0 实例类型 选择实例的主备类型。 单机 存储类型 实例的存储类型决定实例的读写速度。最大吞吐量越高,读写速度越快。 SSD云盘 可用区 对于单机实例,仅需选择单个可用区。 - 时区 由于世界各国家与地区经度不同,地方时也有所不同,因此会划分为不同的时区。时区可在创建实例时选择,后期可修改。 默认 性能规格 实例的CPU和内存。不同性能规格对应不同连接数和最大IOPS。 2vCPUs | 4GB 存储空间 如果存储类型为SSD云盘或极速型SSD,可设置存储空间自动扩容,当存储空间可用率过小时,会自动扩容存储空间。 40GB 磁盘加密 选择是否开启磁盘加密功能。 不加密 虚拟私有云 选择已有的虚拟私有云。 如需重新创建VPC和子网,请参考创建虚拟私有云和子网。 说明: 跨源场景数据源网段和弹性资源池的网段不能重合。 - 数据库端口 默认使用3306端口。 3306 安全组 安全组限制实例的安全访问规则,加强云数据库RDS服务与其他服务间的安全访问。 数据源的安全组需放通DLI弹性资源池的网段。 - 设置密码 设置实例的登录密码。 - 管理员账号 root root 管理员密码 设置管理员密码。 - 参数模板 数据库参数模板就像是数据库引擎配置值的容器,参数模板中的参数可应用于一个或多个相同类型的数据库实例。 系统默认模板:Default-MySQL-5.7 表名大小写 配置表名不区分大小写。 不区分大小写 企业项目 对于已成功关联企业项目的用户,仅需在“企业项目”下拉框中选择目标项目。 default 购买数量 实例购买数量 1 只读实例 为了实现读取能力的弹性扩展,分担数据库压力,您可以在某个区域中创建一个或多个只读实例。 暂不购买 单击“立即购买”,进入规格确认页面。 单击“提交”,完成购买RDS MySQL实例。 实例创建成功后,用户可以在“实例管理”页面对其进行查看和管理。 创建实例过程中,状态显示为“创建中”,创建完成的实例状态显示为“正常”。您可以通过“任务中心”查看详细进度和结果。
-
Flink Jar作业上传配置文件操作流程 自定义(JAR)作业支持上传配置文件。 将配置文件通过程序包管理上传到DLI; 在Flink jar作业的其他依赖文件参数中,选择创建的DLI程序包; 在代码中通过ClassName.class.getClassLoader().getResource("userData/fileName")加载该文件。 ClassName”为需要访问该文件的类名。 userData为固定文件路径名,不支持修改或自定义其他路径名。 fileName为需要访问的文件名。 本节示例适用于Flink 1.12版本。Flink 1.15版本的Jar作业开发指导请参考Flink Jar写入数据到OBS开发指南。
-
请求消息 表2 请求参数 参数名称 是否必选 参数类型 说明 name 是 String 连接名称。 名称只能包含数字、英文字母、下划线和中划线。不能为空。 输入长度不能超过64个字符。 service 是 String 服务名称,目前为CloudTable.OpenTSDB/CloudTable,MRS.OPENTSDB,DWS,RDS,CSS。 说明: 不区分大小写。 security_group_id 是 String 用户指定安全组ID,即为需要建立连接的服务所在的安全组。 network_id 是 String 对应服务的子网网络ID,即为需要建立连接的服务所在的子网。 url 是 String 对应服务对外提供的访问url。长度不能超过512个字符。获取方式请参考表4。 tags 否 Array of Objects 队列的标签。具体请参考表3。 表3 tags参数 参数名称 是否必选 参数类型 说明 key 是 String 标签的键。 说明: 标签的键的最大长度为128个字符,标签的键可以包含任意语种字母、数字、空格和_ . : =+-@ ,但首尾不能含有空格,不能以_sys_开头。 value 是 String 标签的值。 说明: 标签值的最大长度为255个字符,标签的值可以包含任意语种字母、数字、空格和_ . : =+-@ ,但首尾不能含有空格。 表4 各服务URL获取方式 服务名称 URL获取方式 Cloud Table HBase OpenTSDB DWS RDS CSS MRS
-
请求示例 { "name": "test1", "security_group_id": "a07ab107-a4ad-4835-ad09-08a2f2efccdb", "network_id": "e83ba67d-e812-42d3-908d-6ea0b2cc5ecb", "url": "cloudtable-8636-zk2-ldQklrNa.mycloudtable.com:2181,cloudtable-8636-zk3-N9EEH4mI.mycloudtable.com:2181,cloudtable-8636-zk1-78Lt0l8L.mycloudtable.com:2181", "service": "ct" }
-
响应示例 { "is_success": true, "message": "", "object_name": "9561", "object_type": "flink", "count": 2, "privileges": [ { "user_name": "testuser1", "is_admin": true, "privileges": [ "ALL" ] }, { "user_name": "user1", "is_admin": false, "privileges": [ "GET" ] } ] }
-
响应消息 表3 响应参数 参数名称 是否必选 参数类型 说明 is_success 是 Boolean 执行请求是否成功。“true”表示请求执行成功。 message 是 String 系统提示信息。执行成功时,信息可能为空。 object_name 否 String 对象名称。 object_type 否 String 对象类型。 privileges 否 Array of Object 权限信息。具体内容请参考表4。 count 否 Integer 权限总数量。 表4 privileges参数 参数名称 是否必选 参数类型 说明 object 否 String 授权对象,和赋权API中的“object”对应。 is_admin 否 Boolean 判断用户是否为管理员。 user_name 否 String 用户名称,即该用户在当前数据库上有权限。 privileges 否 Array of Strings 该用户在数据库上的权限。
-
快速入门 如果您是首次使用华为云Flexus云服务,您可以根据快速入门快速了解并使用华为云Flexus云服务。本文介绍华为云Flexus云服务各产品的快速入门内容以及文档索引。 产品类型 内容说明 文档索引 Flexus应用服务器L实例 入门指引 介绍Flexus L实例产品基础知识、计费方式、使用流程、了解控制台以及新用户常见问题等,帮助您快速了解并使用Flexus L实例。 使用WordPress应用镜像搭建网站 为您介绍如何使用Flexus L实例的WordPress应用镜像三步快速搭建网站。 使用CentOS系统镜像部署Nginx服务器 介绍如何使用Flexus L实例的CentOS系统镜像部署Nginx服务器。 Flexus L实例快速入门 Flexus云服务器X实例 入门指引 介绍Flexus X实例产品基础知识、计费方式、使用流程、了解控制台以及新用户常见问题等,帮助您快速了解并使用Flexus X实例。 购买并登录Flexus X实例 介绍如何在管理控制台快速购买并登录Flexus X实例。 Flexus X实例快速入门 Flexus云数据库RDS 购买并登录Flexus云数据库RDS 介绍如何购买到Flexus数据库并通过DAS连接Flexus数据库。 Flexus数据库快速入门
-
发布Topic 发布Topic是指设备主动向平台上报自己的属性或消息,详细见设备属性上报接口文档。 在FrmMqttDemo中实现了上报Topic、属性上报功能。 1 2 3 4 5 6 7 8 var appMsg = new MqttApplicationMessage(); appMsg.Payload = Encoding.UTF8.GetBytes(inputString); appMsg.Topic = topic; appMsg.QualityOfServiceLevel = int.Parse(cbOosSelect.SelectedValue.ToString()) == 0 ? MqttQualityOfServiceLevel.AtMostOnce : MqttQualityOfServiceLevel.AtLeastOnce; appMsg.Retain = false; // 上行响应 client.PublishAsync(appMsg).Wait(); 发布Topic后,Demo界面显示如下: 设备上报属性成功后可在设备详情页面查看到上报的属性: 图2 查看上报数据-Demo_smokeDetector 如果在“设备详情”页面没有最新上报数据,请修改产品模型中服务和属性的内容,确保设备上报的服务/属性和产品模型中的服务/属性一致,或者进入“产品基本信息”页面,删除所有服务。 由于是同步命令需要端侧回复响应可参考接口。
-
操作步骤 访问 设备接入服务 ,单击“管理控制台”进入“设备接入”控制台。选择您的实例,单击实例卡片进入。 单击左侧导航栏的“产品”,在产品列表中,找到对应的产品,单击产品进入产品详情页。 在产品详情基本信息页面,单击“自定义模型”,添加服务。 输入“服务ID”、“服务类型”和“服务描述”,然后单击“确定”。 “服务ID”:采用首字母大写的命名方式。比如:WaterMeter、StreetLight。 “服务类型”:建议和服务ID保持一致。 “服务描述”:比如路灯上报的环境光强度和路灯开关状态的属性。 添加服务后,在“添加服务”区域,对属性和命令进行定义。每个服务下,可以包含属性和命令,也可以只包含其中之一,请根据此类设备的实际情况进行配置。 单击步骤4新增的服务ID,在展开的页面单击“新增属性”,在弹出窗口中配置属性的各项参数,然后单击“确定”。 参数 说明 属性名称 建议采用驼峰形式,如batteryLevel、internalTemperature。 数据类型 int:当上报的数据为整数时,可配置为此类型。 long: 当上报的数据为长整型时,可配置为此类型。 decimal:当上报的数据为小数时,可配置为此类型。配置“经纬度”属性时,数据类型建议使用“decimal”。 string:当上报的数据为字符串、枚举值时,可以配置为此类型。如果为枚举值,值之间需要用英文逗号(“,”)分隔。 dateTime:当上报的数据为日期时,可以配置为此类型。 此类型属性上报格式推荐样例:2020-09-01T18:50:20Z或者2020-09-01T18:50:20.200Z jsonObject:当上报的数据为JSON结构体时,可以配置为此类型。 enum: 当上报的数据为枚举值时,可配置为此类型。 搭配参数enumList格式填写,比如状态属性的enumList填写为OPEN,CLOSE,那么属性上报格式样例为"OPEN"或者"CLOSE" boolean: 当上报的数据为布尔值时,可配置为此类型。 此类型属性上报推荐格式样例:true/false 或者 0/1 stringList: 当上报的数据为字符串数组时,可配置为此类型。 此类型属性上报推荐格式样例:["str1","str2","str3"] 访问权限 可读:通过接口可以查询该属性。 可写:通过接口可以修改该属性值。 取值范围 请根据此类设备的实际情况进行配置。 步长 单位 图1 新增属性-batteryLevel 单击“添加命令”,在弹出窗口中配置命令。 “命令名称”:建议采用全大写形式,单词间用下划线连接的命名方式,如DISCOVERY,CHANGE_STATUS。 “下发参数”:单击“新增输入参数”,在弹出窗口中配置下发命令字段的各项参数,然后“确定”。 参数 说明 参数名称 建议采用第一个单词首字母小写,其余单词的首字母大写的命名方式,比如valueChange 数据类型 请根据此类设备的实际情况进行配置。 取值范围 步长 单位 图2 新增命令CHANGE_STATUS 如果要添加命令响应,单击“新增响应参数”,在弹出窗口中配置响应命令字段的各项参数,然后单击“确定”。 参数 说明 参数名称 建议采用第一个单词首字母小写,其余单词的首字母大写的命名方式,比如valueResult 数据类型 请根据此类设备的实际情况进行配置。 取值范围 步长 单位 图3 新增命令响应参数-valueAResult
-
概述 在线开发产品模型前需要创建产品。创建产品需要输入产品名称、协议类型、数据格式、所属行业和设备类型等信息,产品模型会使用这些信息作为设备能力字段取值。 物联网平台 提供了标准模型和厂商模型,这些模型涉及多个领域,模型中提供了已经编辑好的产品模型文件,您可以根据自己的需要对产品模型中的字段进行修改和增删;如果选择自定义产品模型,则需要完整定义产品模型。 本节定义包含一个服务的产品模型为示例,该产品模型包含设备上报数据、下发命令、下发命令响应等场景的服务和字段。
-
上报升级结果 根据PCP协议约定的交互流程,设备在执行完软件升级后,将会向物联网平台上报升级的结果。 设备发送的请求消息 根据PCP消息结构的定义可以得出,设备向物联网平台上报升级结果,各个消息字段的填写如下: 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致,为18。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段的数据类型得出数据区长度为17字节,转换为十六进制为:0011。 数据区:结果码,以上报升级成功为例,结果码为00。当前版本号:升级完成后的版本号,与物联网平台下发的软件版本一致,即v1.0,转换为十六进制为:56312E30000000000000000000000000。 字段 数据类型 描述及要求 结果码 BYTE 0X00升级成功。 0X01设备使用中。 0X04电量不足。 0X05剩余空间不足。 0X09内存不足。 0X0A安装升级包失败。 0X7F内部异常。 当前版本号 BYTE[16] 设备当前版本号。 设备向物联网平台上报升级结果的消息为:FFFE 01 18 0000 0011 0056312E30000000000000000000000000(CRC16校验前),经CRC16计算得到校验码为:C7D2。则替换校验码后设备向物联网平台上报升级结果码流为:FFFE0118C7D200110056312E30000000000000000000000000。 物联网平台发送的应答消息 物联网平台收到设备上报的升级结果消息后,将对设备进行应答,各个消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致:18。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段定义得出该数据长度为1个字节,转换为十六进制为:0001。 数据区:处理成功,则返回00,升级任务不存在80。本示例以返回00处理成功为例进行说明。 字段 数据类型 描述及要求 结果码 BYTE 0X00处理成功。 0X80升级任务不存在。 物联网平台向设备的应答消息为:FFFE 01 18 0000 0001 00 (CRC16校验前),经CRC16计算得到校验码为:AFA1。则替换校验码后物联网平台返回的应答消息为:FFFE0118AFA1000100 。
-
执行软件升级 根据PCP协议约定的交互流程,物联网平台收到设备发送的软件包下载结果通知后,需要通知设备进行升级操作。 物联网平台发送的请求消息 根据PCP消息结构的定义可以得出,物联网平台向设备发送执行软件升级消息,各个消息字段的填写如下: 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致,为17。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段的数据类型得出无数据区,即为0字节,转换为十六进制为:0000。 数据区:无数据区,无需携带该字段。 字段 数据类型 描述及要求 无数据区 物联网平台向设备下发的执行软件升级的消息为:FFFE 01 17 0000 0000(CRC16校验前),经CRC16计算得到校验码为:CF90。则替换校验码后物联网平台向设备发送的消息为:FFFE0117CF900000。 设备发送的应答消息 设备收到物联网平台下发的执行升级消息后,将对收到消息后的执行动作进行应答,各消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致:17。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段定义得出该数据长度为1个字节,转换为十六进制为:0001。 数据区:处理成功,则返回00,其它处理结果请参考数据区定义。本示例以返回00处理成功为例进行说明。 字段 数据类型 描述及要求 结果码 BYTE 0X00处理成功。 0X01设备使用中。 0X04电量不足。 0X05剩余空间不足。 0X09内存不足。 设备向物联网平台应答的消息为:FFFE 01 17 0000 0001 00 (CRC16校验前),经CRC16计算得到校验码为:B725。则替换校验码后设备返回的响应消息为:FFFE0117B725000100 。
-
上报下载结果 根据PCP协议约定的交互流程,设备接收完所有分片数据并组装完软件包后,需要向物联网平台上报软件包的下载结果。 设备发送的请求消息 根据PCP消息结构的定义可以得出,设备向物联网平台发送的上报软件包下载结果消息,各个消息字段的填写如下: 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致,为16。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段的数据类型得出数据区长度为1个字节,转换为十六进制为:0001。 数据区:上报软件包的下载结果,比如下载成功,设备侧上报00。 字段 数据类型 描述及要求 下载状态 BYTE 0X00下载成功。 0X05剩余空间不足。 0X06下载超时。 0X07升级包校验失败。 0X08升级包类型不支持。 设备向物联网平台发送升级包下载结果的消息为:FFFE 01 16 0000 0001 00(CRC16校验前),经CRC16计算得到校验码为:850E。则替换校验码后设备发送的升级包下载结果的消息为:FFFE0116850E000100。 物联网平台的应答消息 物联网平台收到设备上报的软件包下载结果后,将会向设备返回应答消息,各个消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致:16。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段定义得出该数据长度为1个字节,转换为十六进制为:0001。 数据区:处理成功,则返回00,处理失败返回80。本示例以返回00处理成功为例进行说明。 字段 数据类型 描述及要求 结果码 BYTE 0X00处理成功。 0X80升级任务不存在。 物联网平台向设备应答的消息为:FFFE 01 16 0000 0001 00 (CRC16校验前),经CRC16计算得到校验码为:850E。则替换校验码后物联网平台向设备应答的消息为:FFFE0116850E000100。
-
下载升级包 根据PCP协议约定的交互流程,物联网平台通知设备有新的软件版本时,设备向物联网平台请求下载软件包,按照分片的序号进行下载。 设备发送的请求消息 根据PCP消息结构的定义可以得出,设备向物联网平台发送的请求软件包分片的第一条消息,各消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:查询消息码表可知请求升级包的消息码为21,转换为十六进制为:15。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段的数据类型得出数据区长度为18个字节,转换为十六进制为:0012。 数据区:目标版本号为平台下发的新版本通知版本号,即v1.0,转换为十六进制为56312E30000000000000000000000000,分片序号为第0个分片,即0000。 字段 数据类型 描述及要求 目的版本号 BYTE[16] 目的版本号,由ASCII字符组成,位数不足时,后补“0X00”。 分片序号 WORD 表示请求获取的分片序号,从0开始计算,分片的总数为软件包大小除以每个分片的大小并向上取整获得。设备可以保存已经收到的分片,下次直接从缺失的分片开始请求,达到断点续传的效果。 设备向物联网平台发送请求软件包分片的第一条消息为:FFFE 01 15 0000 0012 56312E30000000000000000000000000 0000(CRC16校验前),经CRC16计算得到校验码为:5618。则替换校验码后设备发送的第一条请求分片消息为:FFFE01155618001256312E300000000000000000000000000000。 其它分片请求的消息流只需要替换分片序号后,重新计算并替换CRC16校验码即可,此处就不再展开。 物联网平台的应答消息 物联网平台收到设备的请求软件包分片消息后,将会给设备下发分片的数据。物联网平台向设备响应的第一条请求分片的消息,各消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致:15。 校验码:CRC16计算前先用0000替代。 数据区:先讲数据区再讲数据区长度。结果码:00,分片序号:第0个分片:0000,分片数据:跟软件包定义的内容有关,我们假设软件包内容为HELLO, IoT SOTA!,经ASCII码转换为十六进制为:48454C4C4F2C20496F5420534F544121,共16字节。用户上传软件包时手动输入升级包分片大小为500byte,即最大长度为500字节。这种情况下,无需在数据的后面补充0。 数据区长度:根据数据区的字段定义得出该数据长度为19,转换为十六进制为:0013。 字段 数据类型 描述及要求 结果码 BYTE 0X00处理成功。 0X80升级任务不存在。 0X81指定的分片不存在。 分片序号 WORD 表示返回的分片序号。 分片数据 BYTE[n] 分片的内容,n为实际的分片大小。如果结果码不为0,则不带此字段。 物联网平台向设备发送的第一个软件包分片消息为:FFFE 01 15 0000 0013 00 0000 48454C4C4F2C20496F5420534F544121(CRC16校验前),经CRC16计算得到校验码为:E107。则替换校验码后物联网平台向设备发送的第一个软件包分片消息为:FFFE0115E107001300000048454C4C4F2C20496F5420534F544121。 其它软件包分片的消息流只需要替换分片序号和分片数据后,重新计算并替换CRC16校验码即可,此处就不再展开。
-
下载新版本软件包通知 根据PCP协议约定的交互流程,查询完版本号后,物联网平台下发指令让设备下载新版本的软件包。 物联网平台发送消息 根据PCP消息结构的定义可以得出,物联网平台向设备下发下载新版本软件包通知时,各消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:此处为新版本通知,查询消息码表可以知道新版本通知为20,转换为十六进制为14。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的消息字段可以得出,数据区长度为22个字节,转换为十六进制为:0016。 数据区:根据数据区的定义可知。 目标版本号:由16个字节组成,假设升级的目标版本号为v1.0版本,转换为十六进制并在后面14个字节补充0后得到:56312E30000000000000000000000000。 升级包分片大小:由2个字节组成,单位为byte,用户上传软件包时可以手动输入升级包分片大小,如果不设置默认为500byte,大小为32~500之间。假设为500byte,转换为十六进制后为:01F4。 升级包分片总数:由2个字节组成,由软件包大小除以每个分片的大小并向上取整获得。假设软件包大小为500byte,则分片数量为1,转换为十六进制后为:0001。 检验码:由2个字节组成,目前已废弃,固定为:0000。 字段 数据类型 描述及要求 目的版本号 BYTE[16] 目的版本号,由ASCII字符组成,位数不足时,后补“0X00”。 升级包分片大小 WORD 每个分片的大小 升级包分片总数 WORD 升级包分片总数 升级包校验码 WORD 固定为:0000 将下载新版本软件包通知的消息流组合起来得到:FFFE 01 14 0000 0016 56312E30000000000000000000000000 01F4 0001 0000。前面说了,还要将消息流进行CRC16算法计算得到校验码为02F7。因此,物联网平台向设备通知下载新版本软件包的信息,物联网平台向设备发送的消息流为FFFE011402F7001656312E3000000000000000000000000001F400010000。 设备返回的应答消息 设备收到下载新版本软件包通知后,设备向物联网平台返回应答消息,是否允许设备进行升级,各消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致,为14。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段的数据类型得出数据区长度为1个字节,转换为十六进制为:0001。 数据区:设备根据自身的情况对平台下发的新版本通知进行响应,本示例以设备应答“允许升级”为例进行介绍,得出数据区为:00。其它应答消息请根据应答消息字段进行适配。 字段 数据类型 描述及要求 结果码 BYTE “0X00”允许升级 “0X01”设备使用中 “0X02”信号质量差 “0X03”已经是最新版本 “0X04”电量不足 “0X05”剩余空间不足 “0X09”内存不足 “0X7F”内部异常 将设备给物联网平台的应答消息流组合起来得到:FFFE 01 14 0000 0001 00。前面说了,还要将消息流进行CRC16算法计算得到校验码为D768。因此,设备向平台返回的应答消息流为FFFE0114D768000100。
-
概述 设备的OTA软件升级是基于华为定义的PCP协议进行的,设备侧需根据PCP协议定义的交互流程进行适配开发。下面我们将结合物联网平台与设备的软件升级交互流程,介绍终端设备将如何基于PCP协议构建交互过程中的请求消息和应答消息,帮助您更好的根据PCP协议进行终端侧的软件升级功能开发。 下面我们先了解下PCP消息的结构,PCP协议的请求消息和应答消息都遵循相同的消息结构,主要由这几部分组成: PCP协议消息由:起始标识位、版本号、消息码、校验码、数据区长度和数据区组成,各字段的要求和描述如下表所示。 字段名 字段类型 描述和要求 起始标识 WORD 起始标识,固定为0XFFFE。 版本号 BYTE 高四位预留;低四位表示协议版本号,当前为1。 消息码 BYTE 标识物联网平台与设备之间的请求消息类型,应答消息的消息码和请求消息相同。消息码的定义为: 0-18:预留消息码,暂未使用。 19:查询设备版本。 20:下载新版本软件包通知。 21:请求下载升级包。 22:上报升级包下载结果。 23:执行软件升级。 24:上报升级结果。 25-127:预留消息码,暂未使用。 校验码 WORD 从起始标识到数据区的最后一个字节的CRC16校验值,计算前先把校验码字段置为0,计算完成后把结果写到校验码字段。 说明: CRC16算法:CRC16/CCITT x16+x12+x5+1 数据区长度 WORD 数据区的长度。 数据区 BYTE[n] 可变长度,具体由各个指令定义,可参考下面介绍的各个指令对应的请求消息和应答消息定义。 数据类型 描述 BYTE 无符号一字节整数 WORD 无符号二字节整数 DWORD 无符号四字节整数 BYTE[n] n字节的十六进制数 STRING 字符串
-
查询设备版本号 从设备的软件升级流程(本流程只描述物联网平台与设备基于PCP协议交互的流程)可以看到,首先物联网平台向设备下发查询版本号信息,设备进行应答。 物联网平台发送消息 根据PCP消息结构的定义可以得出,物联网平台向设备下发查询版本号时,各消息字段的填写如下: 起始标识:固定为消息流的前2个字节,固定为FFFE。 版本号:数据类型为1个字节整数,且固定为1,即在消息流中为01。 消息码:数据类型为1个字节整数,查询设备版本的消息码为19,转换为十六进制为13。 校验码:数据类型为2个字节整数,先将校验码置为0000,然后将完整的消息码流进行CRC16的算法计算得到校验码,再将得到的校验码替换原消息中的0000。 数据区长度:数据类型为2个字节整数,代表数据区的消息长度,根据数据区的数据结构可以得出该条消息无数据区,即数据区长度为0000。 数据区:数据区代表要真正发送给设备的数据,根据查询版本信息的数据区定义,该条消息是没有实际要传送的数据的,即无需数据区字段。 字段 数据类型 描述及要求 无数据区 因此将查询版本消息的码流组合起来得到:FFFE 01 13 0000 0000。前面的校验码时讲了,需要将组合后的消息码流进行CRC16算法(物联网平台提供了基于JAVA和C语言的CRC16算法代码样例,您可以直接使用)得到校验码4C9A,然后将该校验码替换原码流中的0000后得到FFFE01134C9A0000,该消息码流即为物联网平台发送给设备的查询版本信息的消息码流。 设备返回的应答消息 设备收到物联网平台要查询设备的软件版本号消息,设备要向物联网平台反馈查询的结果,各消息字段的填写如下。 起始标识固定为:FFFE。 版本号固定为:01。 消息码:与请求的消息码一致,为13。 校验码:CRC16计算前先用0000替代。 数据区长度:根据数据区的字段的数据类型得出数据区长度为17个字节,转换为十六进制为:0011。 数据区:根据数据区的定义可知,处理成功的结果码为00,版本号信息假设为V0.9,将V0.9进行ASCII转码得到56302E39,由于版本号的数据类型为BYTE[16],即16个字节,当前只有4个字节,因此需要在版本号数据后面补0,得到56302E39000000000000000000000000。因此,数据区合并后为0056302E39000000000000000000000000。 字段 数据类型 描述及要求 结果码 BYTE “0X00”处理成功 当前版本号 BYTE[16] 当前版本号,由ASCII字符组成,位数不足时,后补“0X00”。 将查询版本信息的消息流组合起来得到:FFFE 01 13 0000 0011 0056302E39000000000000000000000000。前面讲到,还要将消息流进行CRC16算法计算得到校验码为8DE3。因此,物联网平台向设备查询版本号信息,设备向平台返回的消息流为FFFE01138DE300110056302E39000000000000000000000000。
-
数组及可变长数组数据类型 如果该烟感设备需要支持描述信息上报功能,描述信息描述信息支持数组和可变长度数组两种类型,则按照以下步骤创建消息。 产品模型定义 在烟感产品的开发空间完成产品模型定义。 图40 模型定义-smokedetector携带other_info 编解码插件开发 在烟感产品的开发空间,选择“插件开发”,单击“图形化开发”。 单击“新增消息”,新增消息“other_info”,上报数组类型的描述信息。配置此步骤的主要目的是,将设备上传的数组二进制码流消息解码成JSON格式,以便物联网平台理解。配置示例如下: 消息名:other_info 消息类型:数据上报 添加响应字段:是。添加响应字段后,物联网平台在收到设备上报的数据后,会下发用户设置的响应数据到设备。 响应数据:AAAA0000(默认) 图41 插件开发-新增消息other_info 单击“添加字段”,添加messageId字段,表示消息种类。在本场景中,0x0用于标识上报火灾等级和温度的消息,0x1用于标识只上报温度的消息,0x2用于标识上报描述信息(数组类型)的消息。messageId、数据类型、长度、默认值、偏移值的说明可参考1。 图42 插件开发-添加字段messageId(0x2) 添加other_info字段,“数据类型”选择“array”,表示数组类型的描述信息。在本场景中,“长度”配置为5个字节。字段名、默认值、偏移值的说明可参考2。 图43 插件开发-添加字段other_info为array 单击“新增消息”,新增“other_info2”消息,上报可变长度数组类型的描述信息。配置此步骤的主要目的是,将设备上传的可变长度数组二进制码流消息解码成JSON格式,以便物联网平台理解。配置示例如下: 消息名:other_info2 消息类型:数据上报 添加响应字段:是。添加响应字段后,物联网平台在收到设备上报的数据后,会下发用户设置的响应数据到设备。 响应数据:AAAA0000(默认) 图44 插件开发-新增消息other_info2 单击“添加字段”,添加messageId字段,表示消息种类。在本场景中,0x0用于标识上报火灾等级和温度的消息,0x1用于标识只上报温度的消息,0x3用于标识上报描述信息(可变长度数组类型)的消息。messageId、数据类型、长度、默认值、偏移值的说明可参考1。 图45 插件开发-添加字段messageId(0x3) 添加length字段,表示数组长度。“数据类型”根据可变长度数组的长度进行配置,长度在255以内,配置为“int8u”。长度、默认值、偏移值的说明可参考2。 图46 插件开发-添加字段length 添加other_info字段,数据类型选择“variant”,表示可变长度数组类型的描述信息。“长度关联字段”选择“length”,表示当前可变长数组的长度由上报的length的值决定。“掩码”默认为“0xff”,用来计算该数组实际生效的长度,例如:“长度关联字段”length的值为5,其对应的二进制为:00000101,此时若掩码为0xff,对应的二进制为:11111111,那么两者进行“与“运算之后的结果为00000101,即十进制的5,那么该数组实际生效的长度为5。如上报数据为03051234567890,表示当前上报的数据对应的是messageId为03的的message,可变长数组长度为5,可变长参数other_info对应的码流为1234567890。 图47 插件开发-添加字段other_info为variant 拖动右侧“设备模型”区域的属性字段,与数据上报消息的相应字段建立映射关系。 图48 插件开发-数据上报字段映射关系other_info为varint 单击“保存”,并在插件保存成功后单击“部署”,将编解码插件部署到物联网平台。 图49 插件开发-部署插件 调测编解码插件 在烟感产品的开发空间,选择“在线调试”,并单击“新增测试设备”。 用户可根据自己的业务场景,选择使用真实设备或者虚拟设备进行调测。具体调测步骤请参考在线调试。本文以虚拟设备为例,调测编解码插件。 在弹出的“新增测试设备”窗口,选择“虚拟设备”,单击“确定”,创建一个虚拟设备。虚拟设备名称包含 “DeviceSimulator”字样,每款产品下只能创建一个虚拟设备。 图50 在线调试-创建虚拟设备 单击“调试”,进入调试界面。 图51 在线调试-进入调试 使用设备模拟器上报数组类型的描述信息。 十六进制码流示例:0211223344。02表示messageId,此消息上报数组类型的描述信息;11223344表示描述信息,长度为4个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=null}。描述信息不足5个字节,编解码插件无法解析。 图52 在线调试-模拟数据上报other_info数组1 十六进制码流示例:021122334455。02表示messageId,此消息上报数组类型的描述信息;1122334455表示描述信息,长度为5个字节。 在“应用模拟器”区域查看数据上报的结果:{serviceId: smokedetector, data: {"other_info":"ESIzRFU="}}。描述信息长度为5个字节,编解码插件解析成功。 图53 在线调试-模拟数据上报other_info数组2 十六进制码流示例:02112233445566。02表示messageId,此消息上报数组类型的描述信息;112233445566表示描述信息,长度为6个字节。 在“应用模拟器”区域查看数据上报的结果:{serviceId: smokedetector, data: {"other_info":"ESIzRFU="}}。描述信息长度超过5个字节,编解码插件截取前5个字节进行解析。 图54 在线调试-模拟数据上报other_info数组3 使用设备模拟器上报可变长度数组类型的描述信息。 十六进制码流示例:030101。03表示messageId,此消息上报可变长度数组类型的描述信息;01表示描述信息长度(1个字节),长度为1个字节;01表示描述信息,长度为1个字节。 在“应用模拟器”区域查看数据上报的结果:{serviceId: smokedetector, data: {"other_info":"AQ=="}}。AQ==是01经过base64编码后的值。 图55 在线调试-模拟数据上报other_info可变长数组1 十六进制码流示例:03020102。03表示messageId,此消息上报可变长度数组类型的描述信息;02表示描述信息长度(2个字节),长度为1个字节;0102表示描述信息,长度为2个字节。 在“应用模拟器”区域查看数据上报的结果:{serviceId: smokedetector, data: {"other_info":"AQI="}}。AQI=是01经过base64编码后的值。 图56 在线调试-模拟数据上报other_info可变长数组2 十六进制码流示例:03030102。03表示messageId,此消息上报可变长度数组类型的描述信息;03表示描述信息长度(3个字节),长度为1个字节;0102表示描述信息,长度为2个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=null}。描述信息长度不足3个字节,编解码插件解析失败。 图57 在线调试-模拟数据上报other_info可变长数组3 十六进制码流示例:0303010203。03表示messageId,此消息上报可变长度数组类型的描述信息;03表示描述信息长度(3个字节),长度为1个字节;010203表示描述信息,长度为3个字节。 在“应用模拟器”区域查看数据上报的结果:{serviceId: smokedetector, data: {"other_info":"AQID"}}。AQID是010203经过base64编码后的值。 图58 在线调试-模拟数据上报other_info可变长数组4 十六进制码流示例:030301020304。03表示messageId,此消息上报可变长度数组类型的描述信息;03表示描述信息长度(3个字节),长度为1个字节;01020304表示描述信息,长度为4个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=AQID}。描述信息长度超过3个字节,编解码插件截取前3个字节进行解析,AQID是010203经过base64编码后的值。 图59 在线调试-模拟数据上报other_info可变长数组5 base64编码方式说明 base64编码方式会把3个8位字节(3*8=24)转化为4个6位字节(4*6=24),并在每个6位字节前补两个0,构成4个8位字节的形式。如果要进行编码的码流不足3个字节,则在码流后用0填充,使用0填充的字节经编码输出的字符为“=”。 base64可以将16进制码流当做字符或者数值进行编码,两种方式获得的编码结果不同。以16进制码流01为例进行说明: 把01当作字符,不足3个字符,补1个0,得到010。通过查询ASCII码表,将字符转换为8位二进制数,即:0转换为00110000、1转换为00110001,因此010可以转换为001100000011000100110000(3*8=24)。再转换为4个6位字节:001100、000011、000100、110000,并在每个6位字节前补两个0,得到:00001100、00000011、00000100、00110000。这4个8位字节对应的10进制数分别为12、3、4、48,通过查询base64编码表,获得M(12)、D(3)、E(4),由于3个字符中,最后一个字符通过补0获得,因此第4个8位字节使用“=”表示。最终,把01当做字符,通过base64编码得到MDE=。 把01当作数值(即1),不足3个字符,补两个0,得到100。将数值转换为8位2进制数,即:0转换为00000000、1转换为00000001,因此100可以转换为000000010000000000000000(3*8=24)。在转换为4个6位字节:000000、010000、000000、000000,并在每个6位字节前补两个0,得到:00000000、00010000、00000000、00000000。这4个8位字节对应的10进制数分别为:0、16、0、0,通过查询base64编码表,获得A(0)、Q(16),由于3个数值中,最后两个数值通过补0获得,因此第3、4个8位字节使用“=”表示。最终,把01当作数值,通过base64编码得到AQ==。 总结 当数据类型为数组或可变长度数组时,插件是按照base64进行编解码的:上报数据时,将16进制码流进行base64编码,比如:01编码为“AQ==”;命令下发时,将字符进行base64解码,比如:“AQ==”解码为01。 当某字段的数据类型为可变长度数组时,该字段需要关联长度字段,长度字段的数据类型必须为int。 针对可变长度数组,命令下发和数据上报的编解码插件开发方式相同。 图形化开发的编解码插件使用base64进行编码时,是将16进制码流当做数值进行编码。
-
字符串及可变长字符串的编解码插件 如果该烟感设备需要支持描述信息上报功能,描述信息支持字符串和可变长度字符串两种类型,则按照以下步骤创建消息。 产品模型定义 重新创建一个烟感产品,并在烟感产品的开发空间完成产品模型定义。 图20 模型定义-smokedetector携带other_info 编解码插件开发 在烟感产品的开发空间,选择“插件开发”,单击“图形化开发”。 单击“新增消息”,新增消息“other_info”,上报字符串类型的描述信息。配置此步骤的主要目的是,将设备上传的字符串二进制码流消息解码成JSON格式,以便物联网平台理解。配置示例如下: 消息名:other_info 消息类型:数据上报 添加响应字段:是。添加响应字段后,物联网平台在收到设备上报的数据后,会下发用户设置的响应数据到设备。 响应数据:AAAA0000(默认) 图21 插件开发-新增消息other_info 单击“添加字段”,添加messageId字段,表示消息种类。在本场景中,0x0用于标识上报火灾等级和温度的消息,0x1用于标识只上报温度的消息,0x2用于标识上报描述信息(字符串类型)的消息。messageId、数据类型、长度、默认值、偏移值的说明可参考1。 图22 插件开发-添加字段messageId(0x2) 添加other_info字段,表示字符串类型的描述信息。在本场景中,字符串类型的字段数据类型选择“string”,“长度”配置 6个字节。字段名、默认值、偏移值的说明可参考2。 图23 插件开发-添加字段other_info 单击“新增消息”,新增“other_info2”消息名,配置数据上报消息,上报可变长度字符串类型的描述信息。配置此步骤的主要目的是,将设备上传的可变长度字符串二进制码流消息解码成JSON格式,以便物联网平台理解。配置示例如下: 消息名:other_info2 消息类型:数据上报 添加响应字段:是。添加响应字段后,物联网平台在收到设备上报的数据后,会下发用户设置的响应数据到设备。 响应数据:AAAA0000(默认) 图24 插件开发-新增消息other_info2 添加messageId字段,表示消息种类。在本场景中,0x0用于标识上报火灾等级和温度的消息,0x1用于标识只上报温度的消息,0x3用于标识上报描述信息(可变长度字符串类型)的消息。messageId、数据类型、长度、默认值、偏移值的说明可参考1。 图25 插件开发-添加字段messageId(0x3) 添加length字段,表示可变字符串长度。“数据类型”根据可变长度字符串的长度进行配置,此场景可变字符串长度在255以内,配置为“int8u”。长度、默认值、偏移值的说明可参考2。 图26 插件开发-添加字段length 添加other_info字段,数据类型选择“varstring”,表示可变长度字符串类型的描述信息。“长度关联字段”选择“length”,表示当前可变长字符串的长度由上报的length的值决定。“掩码”默认为“0xff”,用来计算该字段实际生效的长度,例如:“长度关联字段”length的值为5,其对应的二进制为:00000101,此时若掩码为0xff,对应的二进制为:11111111,那么两者进行“与“运算之后的结果为00000101,即十进制的5,那么该字段实际生效的长度为5个字节。如上报数据为03051234567890,表示当前上报的数据对应的是messageId为03的的message,可变长字符串长度为5个字节,可变长参数other_info对应的码流为1234567890。 图27 插件开发-添加字段other_info为varstring 拖动右侧“设备模型”区域的属性字段,与数据上报消息的相应字段建立映射关系。 图28 插件开发-数据上报字段映射关系 单击“保存”,并在插件保存成功后单击“部署”,将编解码插件部署到物联网平台。 图29 插件开发-部署插件 调测编解码插件 在烟感产品的开发空间,选择“在线调试”,并单击“新增测试设备”。 用户可根据自己的业务场景,选择使用真实设备或者虚拟设备进行调测。具体调测步骤请参考在线调试。本文以虚拟设备为例,调测编解码插件。 在弹出的“新增测试设备”窗口,选择“虚拟设备”,单击“确定”,创建一个虚拟设备。虚拟设备名称包含 “DeviceSimulator”字样,每款产品下只能创建一个虚拟设备。 图30 在线调试-创建虚拟设备 单击“调试”,进入调试界面。 图31 在线调试-进入调试 使用设备模拟器上报字符串类型的描述信息。 十六进制码流示例:0231。02表示messageId,此消息上报字符串类型的描述信息;31表示描述信息,长度为1个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=null}。描述信息不足6个字节,编解码插件无法解析。 图32 在线调试-模拟数据上报other_info长度不足 十六进制码流示例:02313233343536。02表示messageId,此消息上报字符串类型的描述信息;313233343536表示描述信息,长度为6个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=123456}。描述信息长度为6个字节,编解码插件解析成功。 图33 在线调试-模拟数据上报other_info长度合适 十六进制码流示例:023132333435363738。02表示messageId,此消息上报字符串类型的描述信息;3132333435363738表示描述信息,长度为8个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=123456}。描述信息长度超过6个字节,编解码插件截取前6个字节进行解析。 图34 在线调试-模拟数据上报other_info长度过长 十六进制码流示例:02013132333435。02表示messageId,此消息上报字符串类型的描述信息;013132333435表示描述信息,长度为6个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=\u000112345}。01在ASCII码表里表示“标题开始”,无法用具体字符表示,因此编解码插件解析为\u0001。 图35 在线调试-模拟数据上报other_info ASCII码 使用设备模拟器上报可变长度字符串类型的描述信息。 十六进制码流示例:030141。03表示messageId,此消息上报可变长度字符串类型的描述信息;01表示描述信息长度;41表示描述信息,长度为1个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=A}。41是A的十六进制ASCII码。 图36 在线调试-模拟数据上报other_info可变长字符串1 十六进制码流示例:03024142。03表示messageId,此消息上报可变长度字符串类型的描述信息;02表示描述信息的长度;4142表示描述信息,长度为2个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=AB}。4142是AB的十六进制ASCII码。 图37 在线调试-模拟数据上报other_info可变长字符串2 十六进制码流示例:030341424344。03表示messageId,此消息上报可变长度字符串类型的描述信息;03表示描述信息长度;41424344表示描述信息,长度为4个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=ABC}。描述信息长度超过3个字节,编解码插件截取前3个字节进行解析,414243是ABC的十六进制ASCII码。 图38 在线调试-模拟数据上报other_info可变长字符串3 十六进制码流示例:0304414243。03表示messageId,此消息上报可变长度字符串类型的描述信息;04表示字符串长度;414243表示描述信息,长度为4个字节。 在“应用模拟器”区域查看数据上报的结果:{other_info=null}。描述信息长度不足4个字节,编解码插件解析失败。 图39 在线调试-模拟数据上报other_info可变长字符串4 总结 当数据类型为字符串或可变长度字符串时,插件是按照ASCII码进行编解码的:上报数据时,将16进制码流解码为对应字符串,比如:21解析为“!”、31解析为“1”、41解析为“A”;下发命令时,将字符串编码对应的16进制码流,比如:“!”编码为21,“1”编码为31,“A”编码为41。 当某字段的数据类型为可变长度字符串时,该字段需要关联长度字段,长度字段的数据类型必须为int。 针对可变长度字符串,命令下发和数据上报的编解码插件开发方式相同。 图形化开发的编解码插件使用ASCII码16进制的标准表对字符串和可变长度字符串进行编解码。解码时(数据上报),如果解析结果无法使用具体字符表示,如:标题开始、正文开始、正文结束等,则使用\u+2字节码流值表示(例如:01解析为\u0001,02解析为\u0002);如果解析结果可以使用具体字符表示,则使用具体字符。
-
数据上报和命令下发 场景说明 有一款烟感设备,具有如下特征: 具有烟雾报警功能(火灾等级)和温度上报功能。 支持远程控制命令,可远程打开报警功能。比如火灾现场温度,远程打开烟雾报警,提醒住户疏散。 支持上报命令执行结果。 产品模型定义 在烟感产品的开发空间,完成产品模型定义。 level:火灾级别,用于表示火灾的严重程度。 temperature:温度,用于表示火灾现场温度。 SET_ALARM:打开或关闭告警命令,value=0表示关闭,value=1表示打开。 图1 模型定义-smokedetector 编解码插件开发 在烟感产品的开发空间,选择“插件开发”,单击“图形化开发”。 单击“新增消息”,新增“smokerinfo”消息。配置此步骤的主要目的是,将设备上传的二进制码流消息解码成JSON格式,以便物联网平台理解。配置示例如下: 消息名:smokerinfo 消息类型:数据上报。 添加响应字段:是。添加响应字段后,物联网平台在收到设备上报的数据后,会下发用户设置的响应数据到设备。 响应数据:AAAA0000(默认) 图2 插件开发-新增消息smokerinfo 单击“添加字段”,勾选“标记为地址域”,添加messageId字段,表示消息类型。在本场景中,上报火灾等级和温度的消息类型是0x0。设备上报消息时,每条消息首个字段就是messageId。如设备上报消息为0001013A,第一个字段00就是表示此条消息是上报火灾级别和温度的消息。后续字段01和013A分别代表火灾级别和温度。如果只有一条数据上报消息和一条命令下发消息,可以不添加messageId字段。 “数据类型”根据数据上报消息种类的数量进行配置。messageId字段默认的数据类型为int8u。 “偏移值”是根据字段位置和字段的字节数的配置自动填充的。messageId为此消息的第一个字段,起始位置为0,字节长度为1,终点位置为1。所以偏移值为0-1。 “长度”是根据“数据类型”的配置自动填充的。 “默认值”可以修改,但必须为十六进制格式,且设备数据上报消息的对应字段必须和此处的默认值保持一致。 图3 插件开发-添加字段messageId 添加level字段,表示火灾级别。 “字段名”只能输入包含字母、数字、_和$,且不能以数字开头的字符。 “数据类型”根据设备上报数据的实际情况进行配置,需要和产品模型相应字段的定义相匹配。产品模型中定义的火灾级别level属性的数据类型为int,最大值为9。所以选择的数据类型为int8u。 “偏移值”是根据字段位置和字段的字节数的配置自动填充的。“level”字段的起始位置就是前一字段的终点,前一字段“messageId”的终点位置为1,所以“level”字段的起始位置为1。“level”字段长度为1个字节,终点为2。所以“偏移值”为1-2。 “长度”根据“数据类型”的配置自动填充。 “默认值”不填。此处火灾级别level不固定,无默认值。 图4 插件开发-添加字段level 添加temperature字段,表示温度。 “数据类型”,在产品模型中,temperature属性的“数据类型”为int,最大值1000,因此在插件中定义temperature字段的“数据类型”为“int16u”,以满足temperature属性的取值范围。 “偏移值”是根据与首字段的间隔的字符数自动配置的。“temperature”字段的起始位置就是前一字段的终点,前一字段“level”的终点位置为2,所以“temperature”字段的起始位置为2。“temperature”字段长度为2个字节,终点为4。所以“偏移值”为2-4。 “长度”根据数据类型的配置自动填充。 “默认值”不填,此处温度temperature的值不固定,无默认值。 图5 插件开发-添加字段temperature 单击“新增消息”,新增“SET_ALARM”消息,设置火灾告警的温度阈值。例如超过60摄氏度,设备上报告警。配置此步骤的主要目的是,将平台下发的JSON格式命令消息编码成二进制数据,以便烟感设备理解。配置示例如下: 消息名:SET_ALARM 消息类型:命令下发 添加响应字段:是。添加响应字段后,设备在接收命令后,可以上报命令执行结果。您可以根据自己的需求,选择是否添加响应字段。 图6 插件开发-新增消息SET_ALARM 单击“添加字段”,添加messageId字段,表示消息类型。例如,设置火灾告警阈值的消息类型为0x3。messageId、数据类型、长度、默认值、偏移值的说明可参考1。 图7 插件开发-添加命令字段messageId(0x3) 添加mid字段。这里的mid字段是由平台生成和下发的,用于将下发的命令和命令下发响应消息关联。mid字段的数据类型默认为int16u。长度、默认值、偏移值的说明可参考2。 图8 插件开发-添加命令字段mid 添加value字段,表示下发命令的参数值。例如,下发火灾告警的温度阈值。数据类型、长度、默认值、偏移值的说明可以参考2。 图9 插件开发-添加命令字段value 单击“添加响应字段”,添加“messageId”字段,表示消息类型。命令下发响应消息为上行消息,需要通过messageId和数据上报消息进行区分。上报火灾告警温度阈值的消息类型为0x4。messageId、数据类型、长度、默认值、偏移值的说明可参考1。 图10 插件开发-添加响应字段messageId(0x4) 添加mid字段。这里的mid字段需要跟平台下发的命令里的mid字段保持一致,用于将下发的命令和命令执行结果进行关联。mid字段的数据类型默认为int16u。长度、默认值、偏移值的说明可参考2。 图11 插件开发-添加响应字段mid 添加errcode字段,用于表示命令执行状态:00表示成功,01表示失败,如果未携带该字段,则默认命令执行成功。errcode字段的数据类型默认为int8u。长度、默认值、偏移值的说明可参考2。 图12 插件开发-添加响应字段errcode 添加result字段,用于表示命令执行结果。例如,设备向平台返回当前的告警阈值。 图13 插件开发-添加响应字段result 拖动右侧“设备模型”区域的属性字段和命令字段,数据上报消息和命令下发消息的相应字段建立映射关系。 图14 插件开发-在线开发插件smokerdetector 单击“保存”,并在插件保存成功后单击“部署”,将编解码插件部署到物联网平台。 图15 插件开发-部署插件 调测编解码插件 在烟感产品的开发空间,选择“在线调试”,并单击“新增测试设备”。 用户可根据自己的业务场景,选择使用真实设备或者虚拟设备进行调测。具体调测步骤请参考在线调试。本文以虚拟设备为例,调测编解码插件。 在弹出的“新增测试设备”窗口,选择“虚拟设备”,单击“确定”,创建一个虚拟设备。虚拟设备名称包含 “DeviceSimulator”字样,每款产品下只能创建一个虚拟设备。 图16 在线调试-创建虚拟设备 单击“调试”,进入调试界面。 图17 在线调试-进入调试 使用设备模拟器进行数据上报。十六进制码流示例:0008016B。00为地址域messageId,08表示火灾级别level,长度为1个字节;016B表示温度,长度为2个字节。 在“应用模拟器”区域查看数据上报的结果:{level=8, temperature=363}。8为十六进制数08转换为十进制的数值;363为十六进制数016B转换为十进制的数值。 在设备模拟器区域看到平台下发的响应数据AAAA0000。 图18 在线调试-模拟数据上报smokerdetector 使用应用模拟器进行命令下发,输入value值为1,可看到应用模拟下发命令{ "serviceId": "Smokeinfo", "method": "SET_ALARM", "paras": "{\"value\":1}" }。 在“设备模拟器”区域查看命令接收的结果:03000101。03为地址域messageId,0001为mid字段,01为十进制数1转换为十六进制的数值。 图19 在线调试-模拟命令下发smokerdetector 使用CoAP的虚拟设备在线调试时,若下发命令后设备模拟器未接收到对应的命令,可以先上报一次属性后,再下发。 总结 如果插件需要对命令执行结果进行解析,则必须在命令和命令响应中定义mid字段。 命令下发的mid是2个字节,对于每个设备来说,mid从1递增到65535,对应码流为0001到FFFF。 设备执行完命令,命令执行结果上报中的mid要与收到命令中的mid保持一致,这样平台才能刷新对应命令的状态。
共100000条
- 1
- ...
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- ...
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
- 1000
- 1001
- 1002
- 1003
- 1004
- 1005
- 1006
- 1007
- 1008
- 1009
- 1010
- 1011
- 1012
- 1013
- 1014
- 1015
- 1016
- 1017
- 1018
- 1019
- 1020
- 1021
- 1022
- 1023
- 1024
- 1025
- 1026
- 1027
- 1028
- 1029
- 1030
- 1031
- 1032
- 1033
- 1034
- 1035
- 1036
- 1037
- 1038
- 1039
- 1040
- 1041
- 1042
- 1043
- 1044
- 1045
- 1046
- 1047
- 1048
- 1049
- 1050
- 1051
- 1052
- 1053
- 1054
- 1055
- 1056
- 1057
- 1058
- 1059
- 1060
- 1061
- 1062
- 1063
- 1064
- 1065
- 1066
- 1067
- 1068
- 1069
- 1070
- 1071
- 1072
- 1073
- 1074
- 1075
- 1076
- 1077
- 1078
- 1079
- 1080
- 1081
- 1082
- 1083
- 1084
- 1085
- 1086
- 1087
- 1088
- 1089
- 1090
- 1091
- 1092
- 1093
- 1094
- 1095
- 1096
- 1097
- 1098
- 1099
- 1100
- 1101
- 1102
- 1103
- 1104
- 1105
- 1106
- 1107
- 1108
- 1109
- 1110
- 1111
- 1112
- 1113
- 1114
- 1115
- 1116
- 1117
- 1118
- 1119
- 1120
- 1121
- 1122
- 1123
- 1124
- 1125
- 1126
- 1127
- 1128
- 1129
- 1130
- 1131
- 1132
- 1133
- 1134
- 1135
- 1136
- 1137
- 1138
- 1139
- 1140
- 1141
- 1142
- 1143
- 1144
- 1145
- 1146
- 1147
- 1148
- 1149
- 1150
- 1151
- 1152
- 1153
- 1154
- 1155
- 1156
- 1157
- 1158
- 1159
- 1160
- 1161
- 1162
- 1163
- 1164
- 1165
- 1166
- 1167
- 1168
- 1169
- 1170
- 1171
- 1172
- 1173
- 1174
- 1175
- 1176
- 1177
- 1178
- 1179
- 1180
- 1181
- 1182
- 1183
- 1184
- 1185
- 1186
- 1187
- 1188
- 1189
- 1190
- 1191
- 1192
- 1193
- 1194
- 1195
- 1196
- 1197
- 1198
- 1199
- 1200
- 1201
- 1202
- 1203
- 1204
- 1205
- 1206
- 1207
- 1208
- 1209
- 1210
- 1211
- 1212
- 1213
- 1214
- 1215
- 1216
- 1217
- 1218
- 1219
- 1220
- 1221
- 1222
- 1223
- 1224
- 1225
- 1226
- 1227
- 1228
- 1229
- 1230
- 1231
- 1232
- 1233
- 1234
- 1235
- 1236
- 1237
- 1238
- 1239
- 1240
- 1241
- 1242
- 1243
- 1244
- 1245
- 1246
- 1247
- 1248
- 1249
- 1250
- 1251
- 1252
- 1253
- 1254
- 1255
- 1256
- 1257
- 1258
- 1259
- 1260
- 1261
- 1262
- 1263
- 1264
- 1265
- 1266
- 1267
- 1268
- 1269
- 1270
- 1271
- 1272
- 1273
- 1274
- 1275
- 1276
- 1277
- 1278
- 1279
- 1280
- 1281
- 1282
- 1283
- 1284
- 1285
- 1286
- 1287
- 1288
- 1289
- 1290
- 1291
- 1292
- 1293
- 1294
- 1295
- 1296
- 1297
- 1298
- 1299
- 1300
- 1301
- 1302
- 1303
- 1304
- 1305
- 1306
- 1307
- 1308
- 1309
- 1310
- 1311
- 1312
- 1313
- 1314
- 1315
- 1316
- 1317
- 1318
- 1319
- 1320
- 1321
- 1322
- 1323
- 1324
- 1325
- 1326
- 1327
- 1328
- 1329
- 1330
- 1331
- 1332
- 1333
- 1334
- 1335
- 1336
- 1337
- 1338
- 1339
- 1340
- 1341
- 1342
- 1343
- 1344
- 1345
- 1346
- 1347
- 1348
- 1349
- 1350
- 1351
- 1352
- 1353
- 1354
- 1355
- 1356
- 1357
- 1358
- 1359
- 1360
- 1361
- 1362
- 1363
- 1364
- 1365
- 1366
- 1367
- 1368
- 1369
- 1370
- 1371
- 1372
- 1373
- 1374
- 1375
- 1376
- 1377
- 1378
- 1379
- 1380
- 1381
- 1382
- 1383
- 1384
- 1385
- 1386
- 1387
- 1388
- 1389
- 1390
- 1391
- 1392
- 1393
- 1394
- 1395
- 1396
- 1397
- 1398
- 1399
- 1400
- 1401
- 1402
- 1403
- 1404
- 1405
- 1406
- 1407
- 1408
- 1409
- 1410
- 1411
- 1412
- 1413
- 1414
- 1415
- 1416
- 1417
- 1418
- 1419
- 1420
- 1421
- 1422
- 1423
- 1424
- 1425
- 1426
- 1427
- 1428
- 1429
- 1430
- 1431
- 1432
- 1433
- 1434
- 1435
- 1436
- 1437
- 1438
- 1439
- 1440
- 1441
- 1442
- 1443
- 1444
- 1445
- 1446
- 1447
- 1448
- 1449
- 1450
- 1451
- 1452
- 1453
- 1454
- 1455
- 1456
- 1457
- 1458
- 1459
- 1460
- 1461
- 1462
- 1463
- 1464
- 1465
- 1466
- 1467
- 1468
- 1469
- 1470
- 1471
- 1472
- 1473
- 1474
- 1475
- 1476
- 1477
- 1478
- 1479
- 1480
- 1481
- 1482
- 1483
- 1484
- 1485
- 1486
- 1487
- 1488
- 1489
- 1490
- 1491
- 1492
- 1493
- 1494
- 1495
- 1496
- 1497
- 1498
- 1499
- 1500
- 1501
- 1502
- 1503
- 1504
- 1505
- 1506
- 1507
- 1508
- 1509
- 1510
- 1511
- 1512
- 1513
- 1514
- 1515
- 1516
- 1517
- 1518
- 1519
- 1520
- 1521
- 1522
- 1523
- 1524
- 1525
- 1526
- 1527
- 1528
- 1529
- 1530
- 1531
- 1532
- 1533
- 1534
- 1535
- 1536
- 1537
- 1538
- 1539
- 1540
- 1541
- 1542
- 1543
- 1544
- 1545
- 1546
- 1547
- 1548
- 1549
- 1550
- 1551
- 1552
- 1553
- 1554
- 1555
- 1556
- 1557
- 1558
- 1559
- 1560
- 1561
- 1562
- 1563
- 1564
- 1565
- 1566
- 1567
- 1568
- 1569
- 1570
- 1571
- 1572
- 1573
- 1574
- 1575
- 1576
- 1577
- 1578
- 1579
- 1580
- 1581
- 1582
- 1583
- 1584
- 1585
- 1586
- 1587
- 1588
- 1589
- 1590
- 1591
- 1592
- 1593
- 1594
- 1595
- 1596
- 1597
- 1598
- 1599
- 1600
- 1601
- 1602
- 1603
- 1604
- 1605
- 1606
- 1607
- 1608
- 1609
- 1610
- 1611
- 1612
- 1613
- 1614
- 1615
- 1616
- 1617
- 1618
- 1619
- 1620
- 1621
- 1622
- 1623
- 1624
- 1625
- 1626
- 1627
- 1628
- 1629
- 1630
- 1631
- 1632
- 1633
- 1634
- 1635
- 1636
- 1637
- 1638
- 1639
- 1640
- 1641
- 1642
- 1643
- 1644
- 1645
- 1646
- 1647
- 1648
- 1649
- 1650
- 1651
- 1652
- 1653
- 1654
- 1655
- 1656
- 1657
- 1658
- 1659
- 1660
- 1661
- 1662
- 1663
- 1664
- 1665
- 1666
- 1667
- 1668
- 1669
- 1670
- 1671
- 1672
- 1673
- 1674
- 1675
- 1676
- 1677
- 1678
- 1679
- 1680
- 1681
- 1682
- 1683
- 1684
- 1685
- 1686
- 1687
- 1688
- 1689
- 1690
- 1691
- 1692
- 1693
- 1694
- 1695
- 1696
- 1697
- 1698
- 1699
- 1700
- 1701
- 1702
- 1703
- 1704
- 1705
- 1706
- 1707
- 1708
- 1709
- 1710
- 1711
- 1712
- 1713
- 1714
- 1715
- 1716
- 1717
- 1718
- 1719
- 1720
- 1721
- 1722
- 1723
- 1724
- 1725
- 1726
- 1727
- 1728
- 1729
- 1730
- 1731
- 1732
- 1733
- 1734
- 1735
- 1736
- 1737
- 1738
- 1739
- 1740
- 1741
- 1742
- 1743
- 1744
- 1745
- 1746
- 1747
- 1748
- 1749
- 1750
- 1751
- 1752
- 1753
- 1754
- 1755
- 1756
- 1757
- 1758
- 1759
- 1760
- 1761
- 1762
- 1763
- 1764
- 1765
- 1766
- 1767
- 1768
- 1769
- 1770
- 1771
- 1772
- 1773
- 1774
- 1775
- 1776
- 1777
- 1778
- 1779
- 1780
- 1781
- 1782
- 1783
- 1784
- 1785
- 1786
- 1787
- 1788
- 1789
- 1790
- 1791
- 1792
- 1793
- 1794
- 1795
- 1796
- 1797
- 1798
- 1799
- 1800
- 1801
- 1802
- 1803
- 1804
- 1805
- 1806
- 1807
- 1808
- 1809
- 1810
- 1811
- 1812
- 1813
- 1814
- 1815
- 1816
- 1817
- 1818
- 1819
- 1820
- 1821
- 1822
- 1823
- 1824
- 1825
- 1826
- 1827
- 1828
- 1829
- 1830
- 1831
- 1832
- 1833
- 1834
- 1835
- 1836
- 1837
- 1838
- 1839
- 1840
- 1841
- 1842
- 1843
- 1844
- 1845
- 1846
- 1847
- 1848
- 1849
- 1850
- 1851
- 1852
- 1853
- 1854
- 1855
- 1856
- 1857
- 1858
- 1859
- 1860
- 1861
- 1862
- 1863
- 1864
- 1865
- 1866
- 1867
- 1868
- 1869
- 1870
- 1871
- 1872
- 1873
- 1874
- 1875
- 1876
- 1877
- 1878
- 1879
- 1880
- 1881
- 1882
- 1883
- 1884
- 1885
- 1886
- 1887
- 1888
- 1889
- 1890
- 1891
- 1892
- 1893
- 1894
- 1895
- 1896
- 1897
- 1898
- 1899
- 1900
- 1901
- 1902
- 1903
- 1904
- 1905
- 1906
- 1907
- 1908
- 1909
- 1910
- 1911
- 1912
- 1913
- 1914
- 1915
- 1916
- 1917
- 1918
- 1919
- 1920
- 1921
- 1922
- 1923
- 1924
- 1925
- 1926
- 1927
- 1928
- 1929
- 1930
- 1931
- 1932
- 1933
- 1934
- 1935
- 1936
- 1937
- 1938
- 1939
- 1940
- 1941
- 1942
- 1943
- 1944
- 1945
- 1946
- 1947
- 1948
- 1949
- 1950
- 1951
- 1952
- 1953
- 1954
- 1955
- 1956
- 1957
- 1958
- 1959
- 1960
- 1961
- 1962
- 1963
- 1964
- 1965
- 1966
- 1967
- 1968
- 1969
- 1970
- 1971
- 1972
- 1973
- 1974
- 1975
- 1976
- 1977
- 1978
- 1979
- 1980
- 1981
- 1982
- 1983
- 1984
- 1985
- 1986
- 1987
- 1988
- 1989
- 1990
- 1991
- 1992
- 1993
- 1994
- 1995
- 1996
- 1997
- 1998
- 1999
- 2000
- 2001
- 2002
- 2003
- 2004
- 2005
- 2006
- 2007
- 2008
- 2009
- 2010
- 2011
- 2012
- 2013
- 2014
- 2015
- 2016
- 2017
- 2018
- 2019
- 2020
- 2021
- 2022
- 2023
- 2024
- 2025
- 2026
- 2027
- 2028
- 2029
- 2030
- 2031
- 2032
- 2033
- 2034
- 2035
- 2036
- 2037
- 2038
- 2039
- 2040
- 2041
- 2042
- 2043
- 2044
- 2045
- 2046
- 2047
- 2048
- 2049
- 2050
- 2051
- 2052
- 2053
- 2054
- 2055
- 2056
- 2057
- 2058
- 2059
- 2060
- 2061
- 2062
- 2063
- 2064
- 2065
- 2066
- 2067
- 2068
- 2069
- 2070
- 2071
- 2072
- 2073
- 2074
- 2075
- 2076
- 2077
- 2078
- 2079
- 2080
- 2081
- 2082
- 2083
- 2084
- 2085
- 2086
- 2087
- 2088
- 2089
- 2090
- 2091
- 2092
- 2093
- 2094
- 2095
- 2096
- 2097
- 2098
- 2099
- 2100
- 2101
- 2102
- 2103
- 2104
- 2105
- 2106
- 2107
- 2108
- 2109
- 2110
- 2111
- 2112
- 2113
- 2114
- 2115
- 2116
- 2117
- 2118
- 2119
- 2120
- 2121
- 2122
- 2123
- 2124
- 2125
- 2126
- 2127
- 2128
- 2129
- 2130
- 2131
- 2132
- 2133
- 2134
- 2135
- 2136
- 2137
- 2138
- 2139
- 2140
- 2141
- 2142
- 2143
- 2144
- 2145
- 2146
- 2147
- 2148
- 2149
- 2150
- 2151
- 2152
- 2153
- 2154
- 2155
- 2156
- 2157
- 2158
- 2159
- 2160
- 2161
- 2162
- 2163
- 2164
- 2165
- 2166
- 2167
- 2168
- 2169
- 2170
- 2171
- 2172
- 2173
- 2174
- 2175
- 2176
- 2177
- 2178
- 2179
- 2180
- 2181
- 2182
- 2183
- 2184
- 2185
- 2186
- 2187
- 2188
- 2189
- 2190
- 2191
- 2192
- 2193
- 2194
- 2195
- 2196
- 2197
- 2198
- 2199
- 2200
- 2201
- 2202
- 2203
- 2204
- 2205
- 2206
- 2207
- 2208
- 2209
- 2210
- 2211
- 2212
- 2213
- 2214
- 2215
- 2216
- 2217
- 2218
- 2219
- 2220
- 2221
- 2222
- 2223
- 2224
- 2225
- 2226
- 2227
- 2228
- 2229
- 2230
- 2231
- 2232
- 2233
- 2234
- 2235
- 2236
- 2237
- 2238
- 2239
- 2240
- 2241
- 2242
- 2243
- 2244
- 2245
- 2246
- 2247
- 2248
- 2249
- 2250
- 2251
- 2252
- 2253
- 2254
- 2255
- 2256
- 2257
- 2258
- 2259
- 2260
- 2261
- 2262
- 2263
- 2264
- 2265
- 2266
- 2267
- 2268
- 2269
- 2270
- 2271
- 2272
- 2273
- 2274
- 2275
- 2276
- 2277
- 2278
- 2279
- 2280
- 2281
- 2282
- 2283
- 2284
- 2285
- 2286
- 2287
- 2288
- 2289
- 2290
- 2291
- 2292
- 2293
- 2294
- 2295
- 2296
- 2297
- 2298
- 2299
- 2300
- 2301
- 2302
- 2303
- 2304
- 2305
- 2306
- 2307
- 2308
- 2309
- 2310
- 2311
- 2312
- 2313
- 2314
- 2315
- 2316
- 2317
- 2318
- 2319
- 2320
- 2321
- 2322
- 2323
- 2324
- 2325
- 2326
- 2327
- 2328
- 2329
- 2330
- 2331
- 2332
- 2333
- 2334
- 2335
- 2336
- 2337
- 2338
- 2339
- 2340
- 2341
- 2342
- 2343
- 2344
- 2345
- 2346
- 2347
- 2348
- 2349
- 2350
- 2351
- 2352
- 2353
- 2354
- 2355
- 2356
- 2357
- 2358
- 2359
- 2360
- 2361
- 2362
- 2363
- 2364
- 2365
- 2366
- 2367
- 2368
- 2369
- 2370
- 2371
- 2372
- 2373
- 2374
- 2375
- 2376
- 2377
- 2378
- 2379
- 2380
- 2381
- 2382
- 2383
- 2384
- 2385
- 2386
- 2387
- 2388
- 2389
- 2390
- 2391
- 2392
- 2393
- 2394
- 2395
- 2396
- 2397
- 2398
- 2399
- 2400
- 2401
- 2402
- 2403
- 2404
- 2405
- 2406
- 2407
- 2408
- 2409
- 2410
- 2411
- 2412
- 2413
- 2414
- 2415
- 2416
- 2417
- 2418
- 2419
- 2420
- 2421
- 2422
- 2423
- 2424
- 2425
- 2426
- 2427
- 2428
- 2429
- 2430
- 2431
- 2432
- 2433
- 2434
- 2435
- 2436
- 2437
- 2438
- 2439
- 2440
- 2441
- 2442
- 2443
- 2444
- 2445
- 2446
- 2447
- 2448
- 2449
- 2450
- 2451
- 2452
- 2453
- 2454
- 2455
- 2456
- 2457
- 2458
- 2459
- 2460
- 2461
- 2462
- 2463
- 2464
- 2465
- 2466
- 2467
- 2468
- 2469
- 2470
- 2471
- 2472
- 2473
- 2474
- 2475
- 2476
- 2477
- 2478
- 2479
- 2480
- 2481
- 2482
- 2483
- 2484
- 2485
- 2486
- 2487
- 2488
- 2489
- 2490
- 2491
- 2492
- 2493
- 2494
- 2495
- 2496
- 2497
- 2498
- 2499
- 2500
- 2501
- 2502
- 2503
- 2504
- 2505
- 2506
- 2507
- 2508
- 2509
- 2510
- 2511
- 2512
- 2513
- 2514
- 2515
- 2516
- 2517
- 2518
- 2519
- 2520
- 2521
- 2522
- 2523
- 2524
- 2525
- 2526
- 2527
- 2528
- 2529
- 2530
- 2531
- 2532
- 2533
- 2534
- 2535
- 2536
- 2537
- 2538
- 2539
- 2540
- 2541
- 2542
- 2543
- 2544
- 2545
- 2546
- 2547
- 2548
- 2549
- 2550
- 2551
- 2552
- 2553
- 2554
- 2555
- 2556
- 2557
- 2558
- 2559
- 2560
- 2561
- 2562
- 2563
- 2564
- 2565
- 2566
- 2567
- 2568
- 2569
- 2570
- 2571
- 2572
- 2573
- 2574
- 2575
- 2576
- 2577
- 2578
- 2579
- 2580
- 2581
- 2582
- 2583
- 2584
- 2585
- 2586
- 2587
- 2588
- 2589
- 2590
- 2591
- 2592
- 2593
- 2594
- 2595
- 2596
- 2597
- 2598
- 2599
- 2600
- 2601
- 2602
- 2603
- 2604
- 2605
- 2606
- 2607
- 2608
- 2609
- 2610
- 2611
- 2612
- 2613
- 2614
- 2615
- 2616
- 2617
- 2618
- 2619
- 2620
- 2621
- 2622
- 2623
- 2624
- 2625
- 2626
- 2627
- 2628
- 2629
- 2630
- 2631
- 2632
- 2633
- 2634
- 2635
- 2636
- 2637
- 2638
- 2639
- 2640
- 2641
- 2642
- 2643
- 2644
- 2645
- 2646
- 2647
- 2648
- 2649
- 2650
- 2651
- 2652
- 2653
- 2654
- 2655
- 2656
- 2657
- 2658
- 2659
- 2660
- 2661
- 2662
- 2663
- 2664
- 2665
- 2666
- 2667
- 2668
- 2669
- 2670
- 2671
- 2672
- 2673
- 2674
- 2675
- 2676
- 2677
- 2678
- 2679
- 2680
- 2681
- 2682
- 2683
- 2684
- 2685
- 2686
- 2687
- 2688
- 2689
- 2690
- 2691
- 2692
- 2693
- 2694
- 2695
- 2696
- 2697
- 2698
- 2699
- 2700
- 2701
- 2702
- 2703
- 2704
- 2705
- 2706
- 2707
- 2708
- 2709
- 2710
- 2711
- 2712
- 2713
- 2714
- 2715
- 2716
- 2717
- 2718
- 2719
- 2720
- 2721
- 2722
- 2723
- 2724
- 2725
- 2726
- 2727
- 2728
- 2729
- 2730
- 2731
- 2732
- 2733
- 2734
- 2735
- 2736
- 2737
- 2738
- 2739
- 2740
- 2741
- 2742
- 2743
- 2744
- 2745
- 2746
- 2747
- 2748
- 2749
- 2750
- 2751
- 2752
- 2753
- 2754
- 2755
- 2756
- 2757
- 2758
- 2759
- 2760
- 2761
- 2762
- 2763
- 2764
- 2765
- 2766
- 2767
- 2768
- 2769
- 2770
- 2771
- 2772
- 2773
- 2774
- 2775
- 2776
- 2777
- 2778
- 2779
- 2780
- 2781
- 2782
- 2783
- 2784
- 2785
- 2786
- 2787
- 2788
- 2789
- 2790
- 2791
- 2792
- 2793
- 2794
- 2795
- 2796
- 2797
- 2798
- 2799
- 2800
- 2801
- 2802
- 2803
- 2804
- 2805
- 2806
- 2807
- 2808
- 2809
- 2810
- 2811
- 2812
- 2813
- 2814
- 2815
- 2816
- 2817
- 2818
- 2819
- 2820
- 2821
- 2822
- 2823
- 2824
- 2825
- 2826
- 2827
- 2828
- 2829
- 2830
- 2831
- 2832
- 2833
- 2834
- 2835
- 2836
- 2837
- 2838
- 2839
- 2840
- 2841
- 2842
- 2843
- 2844
- 2845
- 2846
- 2847
- 2848
- 2849
- 2850
- 2851
- 2852
- 2853
- 2854
- 2855
- 2856
- 2857
- 2858
- 2859
- 2860
- 2861
- 2862
- 2863
- 2864
- 2865
- 2866
- 2867
- 2868
- 2869
- 2870
- 2871
- 2872
- 2873
- 2874
- 2875
- 2876
- 2877
- 2878
- 2879
- 2880
- 2881
- 2882
- 2883
- 2884
- 2885
- 2886
- 2887
- 2888
- 2889
- 2890
- 2891
- 2892
- 2893
- 2894
- 2895
- 2896
- 2897
- 2898
- 2899
- 2900
- 2901
- 2902
- 2903
- 2904
- 2905
- 2906
- 2907
- 2908
- 2909
- 2910
- 2911
- 2912
- 2913
- 2914
- 2915
- 2916
- 2917
- 2918
- 2919
- 2920
- 2921
- 2922
- 2923
- 2924
- 2925
- 2926
- 2927
- 2928
- 2929
- 2930
- 2931
- 2932
- 2933
- 2934
- 2935
- 2936
- 2937
- 2938
- 2939
- 2940
- 2941
- 2942
- 2943
- 2944
- 2945
- 2946
- 2947
- 2948
- 2949
- 2950
- 2951
- 2952
- 2953
- 2954
- 2955
- 2956
- 2957
- 2958
- 2959
- 2960
- 2961
- 2962
- 2963
- 2964
- 2965
- 2966
- 2967
- 2968
- 2969
- 2970
- 2971
- 2972
- 2973
- 2974
- 2975
- 2976
- 2977
- 2978
- 2979
- 2980
- 2981
- 2982
- 2983
- 2984
- 2985
- 2986
- 2987
- 2988
- 2989
- 2990
- 2991
- 2992
- 2993
- 2994
- 2995
- 2996
- 2997
- 2998
- 2999
- 3000
- 3001
- 3002
- 3003
- 3004
- 3005
- 3006
- 3007
- 3008
- 3009
- 3010
- 3011
- 3012
- 3013
- 3014
- 3015
- 3016
- 3017
- 3018
- 3019
- 3020
- 3021
- 3022
- 3023
- 3024
- 3025
- 3026
- 3027
- 3028
- 3029
- 3030
- 3031
- 3032
- 3033
- 3034
- 3035
- 3036
- 3037
- 3038
- 3039
- 3040
- 3041
- 3042
- 3043
- 3044
- 3045
- 3046
- 3047
- 3048
- 3049
- 3050
- 3051
- 3052
- 3053
- 3054
- 3055
- 3056
- 3057
- 3058
- 3059
- 3060
- 3061
- 3062
- 3063
- 3064
- 3065
- 3066
- 3067
- 3068
- 3069
- 3070
- 3071
- 3072
- 3073
- 3074
- 3075
- 3076
- 3077
- 3078
- 3079
- 3080
- 3081
- 3082
- 3083
- 3084
- 3085
- 3086
- 3087
- 3088
- 3089
- 3090
- 3091
- 3092
- 3093
- 3094
- 3095
- 3096
- 3097
- 3098
- 3099
- 3100
- 3101
- 3102
- 3103
- 3104
- 3105
- 3106
- 3107
- 3108
- 3109
- 3110
- 3111
- 3112
- 3113
- 3114
- 3115
- 3116
- 3117
- 3118
- 3119
- 3120
- 3121
- 3122
- 3123
- 3124
- 3125
- 3126
- 3127
- 3128
- 3129
- 3130
- 3131
- 3132
- 3133
- 3134
- 3135
- 3136
- 3137
- 3138
- 3139
- 3140
- 3141
- 3142
- 3143
- 3144
- 3145
- 3146
- 3147
- 3148
- 3149
- 3150
- 3151
- 3152
- 3153
- 3154
- 3155
- 3156
- 3157
- 3158
- 3159
- 3160
- 3161
- 3162
- 3163
- 3164
- 3165
- 3166
- 3167
- 3168
- 3169
- 3170
- 3171
- 3172
- 3173
- 3174
- 3175
- 3176
- 3177
- 3178
- 3179
- 3180
- 3181
- 3182
- 3183
- 3184
- 3185
- 3186
- 3187
- 3188
- 3189
- 3190
- 3191
- 3192
- 3193
- 3194
- 3195
- 3196
- 3197
- 3198
- 3199
- 3200
- 3201
- 3202
- 3203
- 3204
- 3205
- 3206
- 3207
- 3208
- 3209
- 3210
- 3211
- 3212
- 3213
- 3214
- 3215
- 3216
- 3217
- 3218
- 3219
- 3220
- 3221
- 3222
- 3223
- 3224
- 3225
- 3226
- 3227
- 3228
- 3229
- 3230
- 3231
- 3232
- 3233
- 3234
- 3235
- 3236
- 3237
- 3238
- 3239
- 3240
- 3241
- 3242
- 3243
- 3244
- 3245
- 3246
- 3247
- 3248
- 3249
- 3250
- 3251
- 3252
- 3253
- 3254
- 3255
- 3256
- 3257
- 3258
- 3259
- 3260
- 3261
- 3262
- 3263
- 3264
- 3265
- 3266
- 3267
- 3268
- 3269
- 3270
- 3271
- 3272
- 3273
- 3274
- 3275
- 3276
- 3277
- 3278
- 3279
- 3280
- 3281
- 3282
- 3283
- 3284
- 3285
- 3286
- 3287
- 3288
- 3289
- 3290
- 3291
- 3292
- 3293
- 3294
- 3295
- 3296
- 3297
- 3298
- 3299
- 3300
- 3301
- 3302
- 3303
- 3304
- 3305
- 3306
- 3307
- 3308
- 3309
- 3310
- 3311
- 3312
- 3313
- 3314
- 3315
- 3316
- 3317
- 3318
- 3319
- 3320
- 3321
- 3322
- 3323
- 3324
- 3325
- 3326
- 3327
- 3328
- 3329
- 3330
- 3331
- 3332
- 3333
- 3333
推荐文章