Skip to content
  • 版块
  • 最新
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
品牌标识

AIRIOT智慧系统搭建平台经验交流

  1. 主页
  2. 设备接入
  3. 设备接入-TCP Server驱动设备接入

设备接入-TCP Server驱动设备接入

已定时 已固定 已锁定 已移动 设备接入
帖子 发布者 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • guangdaG 离线
    guangdaG 离线
    guangda
    写于 最后由 编辑
    #1
    TCP Server 驱动 v3.2

    该驱动内置了一个 tcp server 服务, 驱动启动后可以接收客户端的连接和数据, 同时也可以向客户端发送数据. 如果使用容器部署时, 需要将 tcp 服务端口开放.

    注: 每个驱动实例只能添加一个模型
    

    配置说明
    以下内容为 tcp-server 驱动的配置项
    e1adb1bf-c703-4a57-b4c2-1d99e7358b11-image.png

    数据处理流程说明

    • 当接收到客户端发送的数据时, 会读取所有的发送数据并存放到 Buffer 中, 然后调用 数据包拆分脚本

    • 列表数据包拆分脚本 从 Buffer 中提取完整的数据包信息或.

    脚本说明
    脚本语言: JavasScript ECMAScript 5.1

    驱动使用时要求提供 数据包拆分脚本, 数据处理脚本 和 指令处理脚本 3 个脚本函数来处理接收和发送数据过程中的协议和数据格式问题.

    在脚本的上下文中内置了 Buffer 包, 可用于处理接收或发送二进制数据.

    除此之外, 还内置了 lodash, crypto-js, moment, xml-js 和 formulajs(Excel函数) 包.

    注: 所有的脚本函数名必须为 **handler**
    

    客户端对象

    在 数据包拆分脚本, 数据处理脚本, 指令处理脚本 和 连接处理脚本 函数的参数中提供了 client 对象, 该对象为当前 TCP 连接客户端对象, 可以通过该对象实现向客户端发送数据的功能. 例如: 向客户端发送 ack 信息等.

    该对象提供了以下函数:

    register
    用于注册设备. 接收到客户端发送的设备注册信息时, 在脚本函数中通过调用 client 对象中的 register 函数注册该设备, 驱动会将该设备与当前连接绑定. 当需要向设备发送指令时, 会通过该绑定关系向对应的连接发送数据. 如果协议未定义设备注册, 会向上次接收到该设备数据的连接发送. 详细信息见 设备与连接绑定关系说明

    参数说明
    0dc85afe-678b-41e7-899a-3bada00a6765-image.png
    返回值

    string 或 undefined 如果参数不正确、部分设备标识错误或对应的设备不存在时返回 string, 内容为错误说明. 如果所有设备注册成功, 返回 undefined

    示例
    4096229b-c771-4385-977a-2077e46cc730-image.png

    unregister
    用于注销设备. 注销设备与连接的绑定关系, 参数及返回值说明同 register

    示例
    abc18c4c-7865-420a-9eb7-ac059b4a1762-image.png
    send
    用于向客户端发送数据. 例如: 在接收到数据时向客户端发送 ack 信息.

    参数说明
    1d304e7c-80ff-49df-a0a3-81c157fe1611-image.png

    返回值

    string 或 undefined 如果参数不正确(字节数组为空或空数组)或发送失败则返回 string 内容为错误说明, 如果发送成功则返回 undefined.

    示例

    c61fd574-754a-4952-8fb5-afadea29a4d2-image.png

    getRemoteAddr
    用于获取客户端地址信息.

    参数说明

    无

    返回值

    string. 格式: IP:Port. 例如: 192.0.2.1:25

    示例
    50a7afa1-8dd6-4209-a275-fbb270cb1863-image.png

    getRemoteIp

    用于获取客户端 IP 地址信息.

    参数说明
    无

    返回值

    string. 例如: 192.0.2.1

    示例
    e39bcb3f-18eb-4a79-b028-68b7e9d0cc21-image.png

    reportCommand
    上报指令执行结果. 有些场景指令的执行结果反馈是异步的, 在指令发送后, 过一段时间才会收到响应报文, 此时可以在接收到响应报文时通过 client.reportCommand(...) 方法上报指令执行结果.

    参数说明
    38fb5e91-7099-44b6-b7b9-085aeb660d81-image.png

    注: serialNo 为平台在发送指令时生成, 会传入到 指令处理脚本 中, 当指令执行结果为异步反馈时, 可以将 serialNo 保存到 设备上下文 中, 以便在后续 reportCommand 使用
    

    返回值

    string 或 undefined. 如果返回 undefined 则表示发送成功, 否则返回数据为错误原因.

    示例

    f49c2e3e-f03d-439b-be37-64312c749368-image.png

    getMediaFile
    请求媒体库文件

    参数说明
    14572741-3f26-4d07-a615-4a46d9370405-image.png
    返回值
    7782a7f0-afff-44e6-94ee-c7b87f7cecc1-image.png

    示例
    fd16f150-7277-4b91-aed6-ec69f548f849-image.png

    getMediaFileByURL
    请求媒体库文件

    参数说明
    7fe258e2-b4a5-4a27-b7ec-9991bfbc6797-image.png
    返回值
    d5ef901b-8162-4c9e-a5b1-173908fa4f50-image.png
    示例
    b53bf6dc-bd6c-421f-af5b-03d2f474b1b2-image.png

    uploadMediaFile
    上传文件到媒体库

    参数说明
    c7979dcc-5d78-4c0e-8841-974e0e15ce27-image.png
    返回值
    2e6182c3-7965-4646-964c-2ec084d35b6f-image.png
    示例
    d493184f-0921-4738-842e-cceed83e5171-image.png

    deleteMediaFile
    删除媒体库文件

    参数说明
    d3f466ce-8f34-483d-bcf8-6b1bd7b0e601-image.png

    返回值
    be98075f-fea0-4850-86ff-359166afbedd-image.png
    示例
    6d9ff39b-1e11-4e7a-8707-e55a879995f8-image.png

    saveWorkTableRow
    向工作表写入一条数据

    参数说明
    425f0962-7f7e-408b-837d-e7696a3a899b-image.png
    返回值
    3573b9c8-8c64-4c34-9d01-27eda8e6c39e-image.png
    示例
    7b149b63-aea6-43fb-9aed-22ec539d91f9-image.png

    updateWorkTableRow
    更新工作表中的数据

    7d23d55e-ea9e-4db1-aa1a-02cadeaa92a4-image.png

    updateNodeById
    根据资产标识更新资产数据
    fed8201c-ae9e-4b25-8ca0-4749442d75a5-image.png

    getContext
    用于获取上下文对象, 可以在上下文中存储数据. 详细信息

    注: 第一次调用的时候才会创建上下文
    

    e1a917e2-b163-4cd4-8d77-2f185a1770ef-image.png

    getDeviceContext
    用于获取设备上下文对象, 使用设备标识作为上下文标识, 可以在上下文中存储数据. 详细信息

    与 getContext 不同的是, 当设备被删除后, 重启驱动时会自动清理被删除设备的上下文对象.

    注: 第一次调用的时候才会创建上下文
    
    

    46c06d7d-2229-4f63-a8ab-4e2ab1455f95-image.png

    removeContext
    删除上下文对象
    817db45b-91b8-4e79-a497-a69e68ccdbd5-image.png

    removeDeviceContext
    删除设备上下文对象
    778d600d-f918-4ecc-a593-ff266d7541b7-image.png

    getContextIds
    获取全部上下文标识(不包含设备上下文)
    8df06010-e339-462b-812d-e861b033aa53-image.png

    getDeviceContextIds
    获取全部设备上下文标识(只包含设备上下文)
    52c6ee2e-46f6-4ccb-b42b-305068b39763-image.png

    context
    上下文对象, 用来存储数据, 上下文中的数据可以在不同的脚本中共享. 例如: 可以在 指令处理脚本中 写入数据, 然后从 数据处理脚本 中读取数据. 不同上下文彼此独立, 互不影响.

    注: 可以根据需求创建多个上下文对象, 但是上下文对象以及上下文中的数据需要及时清理, 否则会造成 **OOM** 问题, 导致驱动程序崩溃.
    

    put
    用于向上下文中存储数据.

    注: 存入的数据需要自行清理, 否则可能导致 OOM 等问题.
    

    4d5dbecf-5811-4d19-9a55-ed1bff46ecf9-image.png

    containsKey
    判断上下文中是否存在指定的 key
    b98c0328-b817-4aed-80d2-d7d2e5db7b80-image.png

    get
    从上下文中获取指定的 key 对应的数据. 如果 key 不存在则返回 undefined
    8295a643-b047-413a-9b2d-f4af29a6d570-image.png

    getAndRemove
    从上下文中获取指定的 key 对应的数据并且在返回后 删除 该 key. 如果 key 不存在则返回 undefined.

    注: 该函数返回后, 再使用 get 或 getAndRemove 均返回 undefined.
    

    cd5a47ff-496d-4bc6-940a-f42d203913fd-image.png

    remove
    从上下文中删除指定的 key, 如果 key 不存在则不执行任何操作.
    3ae45176-54ab-400d-a8cd-8fe7f9b8ea4b-image.png

    内置函数
    crc 校验
    驱动中内置了 crc 对象, 可以在脚本中直接使用 crc 对象中的校验函数.

    • 使用 checksum16 实现 crc16 校验

    ce27119c-45cc-4cee-8643-7e3083173e97-image.png

    • 使用 checksum32 实现 crc32 校验

    381f450d-21a1-41fa-b686-3e5a81bc450b-image.png

    • 使用 checksum64 实现 crc64 校验

    cfd0e938-ddb0-4e39-8f14-3eb1f6d98ef0-image.png

    • 使用 checksumModbus 实现 modbus 协议 crc 校验

    modbus 校验为 crc16, 所以校验码类型为 uint16. 另外, checksumModbus 不需要 poly 多项式参数.
    176c6f8b-e660-4926-9ec9-44ab449689da-image.png

    数据包拆分脚本

    该脚本用于处理接收数据过程中的半包和粘包问题, 该函数需要根据协议和数据格式判断接收到的字节数组中是否包含完整的数据包, 如果包含了完整数据包则返回完据包的起始位置和长度. 或者当数据包有错误时丢掉该数据包或有问题部分的数据.

    如果字节数组中不包含完整的数据包, 直接返回 undefined 表示需要从客户端接收更多的数据.

    函数定义如下:
    cc5d7ef2-6526-44bb-ab5b-ac5363ddf1e0-image.png
    参数说明
    8def868c-efd1-421e-b002-07fa02a1b162-image.png
    返回值说明

    • 当字节数组中包含完整数据包时, 返回包含 package 字段的对象.
    • 如果字节数组中存在错误, 则返回包含 drop 字段的对象, 丢弃掉错误的数据.
    • 如果字节数组中即不包含完整的数据包也不存在错误, 直接返回 undefined, 表示需要从客户端接收更多的数据. | 参数名 | 参数类型 | 参数说明 | 示例值 | | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------- | | package | object | 数据包信息, 如果要丢弃数据该字段不需要返回 | {"start": 0, "length": 128, "next": 129} | | start | 数值 | 数据包在 data | | 中的起始位置 | 4 表示第 5 个字节为数据包的起始位置 | | length | 数值 | 数据包的长度, 表示从 start | | 后多少个字节为一个完整的数据包 | start=4, length=128 表示从第 5 个字节开始(包括第 5 个字节)连续 128 个字节为一个完整的数据包 | | next | 数值 | 下一个数据包的起始位置 | 例如: 在使用 \r\n | | 作为数据包间的固定分隔符时, 下一个数据包的起始位置应该为 start + length + 2 | | drop | 数值 | 要丢弃的字节数量, 即丢弃字节数组中 data[0:drop] | | 内容 | 128 表示丢弃前 128 个字节. 一般用于数据包错误时丢弃掉错误的数据包场景 |

    正常接收数据
    当数据包拆分脚本返回以下内容时, 表示已接收到的数据中包含了完整的数据包. 该数据包在所有数据中的起始位置为 0, 长度为 128, 下一个数据包的起始位置为 129

    d890d8fe-8c5f-40e1-955e-68dc2200c3ff-image.png

    例如, 使用 \r\n 作为数据包间的分隔符, 以解析该数据时 {"a":1,"b":2}\r\n{"a":3,"b":4}\r\n, 拆分结果为 {"package":{"start":0,"length":13,"next":15}}. 此时, 数据处理脚本 中接收到的数据为 {"a":1,"b":2}, 并不会包含 \r\n, 而下一次数据拆分脚本接收到的数据为 {"a":3,"b":4}\r\n.

    包含错误或不完整数据包时
    返回以下内容时, 表示接收到的数据不完整, 需要丢弃 0 - 12 部分内容.
    d881ddb0-56d6-42eb-8a2a-0d4c4f39a4c7-image.png
    例如, 接收到的内容为 :1,"b":2}\r\n{"a":3,"b":4}\r\n 时, :1,"b":2}\r\n 为不完整的数据包需要丢弃, 则需要返回 {"drop":11}. 下一次数据拆分脚本接收到的数据为 {"a":3,"b":4}\r\n

    不包含完整的数据包和错误包时
    例如, 接收到的数据为 {"a":1, 未找到分隔符 \r\n, 此时返回 undefined 表示需要接收更多的数据. 当客户端发送 "b":2}\r\n{"a":3,"b":4}\r\n 数据时, 会再次调用 数据包拆分脚本, 此时 Buffer 中的数据为 {"a":1,"b":2}\r\n{"a":3,"b":4}\r\n, 此时可以提取出完整的数据包.

    注: 如果返回结果中同时包含了 drop 和 package 字段并且 drop 的值大于 0 时, 只做丢弃数据处理.

    示例
    b060a3cd-b68d-4ef4-b13f-0a1cd53df663-image.png
    驱动内置数据包拆包函数

    • 固定长度头 该函数会取前 N 个字节作为长度信息, 然后根据长度信息读取主体内容. +--------+-----------+ | Length | Data | +--------+-----------+

    在数据包拆分脚本中直接使用内置的拆分函数, 如下所示:
    c1abdf26-065a-440c-8185-6617af1c22fd-image.png

    • 固定分隔符 该函数会使用固定分隔符拆分数据包. 使用方式如下所示:

    c1f4931b-5cb3-4ce7-8927-3b404f01e96e-image.png

    • 固定开始和结束符 该函数会读取指定开始符和结束符之间的数据做为一个完整的数据包. 使用方式如下所示:

    384d4c7a-cea5-4fc6-8b4a-b797941c2bda-image.png

    数据处理脚本
    该脚本用于处理 数据包拆分脚本 函数解析得到的完整数据包, 根据协议和数据格式将数据包解析为平台定义的数据格式.

    函数定义如下:

    561aff23-f9e6-4b5b-853d-5f070ca6ab6c-image.png
    参数说明
    7bd38951-e2e8-4eae-be95-bb8667a2e8a2-image.png
    返回值
    91e01ec0-54f5-4048-8ed0-fddd77a53ef3-image.png

    注: 返回值必须为 **Object[]** 或 **undefined** 其中之一. 返回空数组表示未从接收到的数据中解析出有效数据, **undefined**表示无返回结果, 驱动程序无须处理返回结果. 例如: 接收到的数据为心跳数据, 不包含采集数据.
    

    示例
    6a5707d5-d8f3-4076-83d5-7510646c798b-image.png

    指令处理脚本

    该脚本用于将发送的指令内容转换为字节数组, 当向设备发送指令时, 驱动会将要发送的内容先经过 命令处理脚本 函数处理, 返回结果作为实际发送的内容.

    函数定义如下:

    ee9ca845-f803-4f3c-b752-e72d2219a635-image.png
    参数说明
    95822d23-8528-4a50-9781-eeaca41608bf-image.png
    指令格式如下:

    以 test 指令为例
    055bb6ec-a0b1-41bd-916f-838de4a11ac4-image.png

    04a32c43-ebf3-44bb-ade0-b3040ea54905-image.png

    注: ops.value 通常为实际发送的内容, 该字段为必填值. opts 为数组, 目前长度固定为 1.
    
    当要发送的数据内容比较复杂时, 可以先转发送内容转换为 base64 格式的字符串, 然后在在指令脚本中再进行 base64 解码后再发送.
    

    返回值说明

    必须值必须为 Buffer 对象.

    注: 可以使用 Buffer.from("this is a string"") 等方法创建 Buffer 对象. 关于 Buffer 的使用说明可以点击查看

    示例

    d580b020-a33b-4732-b58d-f4c171b1f0ab-image.png

    连接处理脚本
    当客户端连接到驱动或断开时, 会调用 连接处理脚本.

    函数定义如下:
    373a3ac8-6af6-434f-a237-61230a280d45-image.png
    参数说明
    e15c50c2-bd5e-4315-807c-b84f67015410-image.png

    返回值说明

    无返回值

    示例
    9e8dc912-0d9f-402b-aab8-aa06bae361ef-image.png

    设备与连接绑定关系说明
    设备与连接关系绑定, 主要用于向设备发送指令时, 驱动会根据该绑定关系确认通过哪个连接发送指令数据. 绑定关系的创建有以下两种:

    • 当协议中定义了设备注册功能时, 由 数据处理脚本 函数在接收到设备注册数据包时, 通过调用 client 中的 register 向驱动注册设备实现设备与连接折绑定.
    • 当协议中未定义设备注册功能时, 驱动会自动记录每个设备是由哪个连接上报实时数据的(设备每次上传实时数据时都会自动更新), 当驱动下发指令时, 会自动根据该信息向对应的连接发送指令数据.
    注: 如果通过 **register** 函数注册了设备时, 会忽略根据实时数据建立的绑定关系. 如果协议中未定义设备注册功能并且设备未上报过实时数据时, 无法通过实时数据建立绑定关系, 此时无法向该设备发送数据
    
    1 条回复 最后回复
    0
  • guangdaG 离线
    guangdaG 离线
    guangda
    写于 最后由 编辑
    #2

    链接tcp-server驱动,调试工具链接不上端口(运维管理地址的端口号),检查tcp-server驱动的四个处理脚本是否全部修改保存。驱动案例脚本是展示的功能,不生效,修改保存后才会生效。再点击重启驱动

    image.png

    1 条回复 最后回复
    0
  • guangdaG 离线
    guangdaG 离线
    guangda
    写于 最后由 编辑
    #3

    windows测试工具链接端口前,先检查端口是否被监听
    netstat -ano|findstr 端口

    image.png

    1 条回复 最后回复
    0

  • 登录

  • 没有帐号? 注册

  • 登录或注册以进行搜索。
  • 第一个帖子
    最后一个帖子
0
  • 版块
  • 最新
  • 标签
  • 热门
  • 用户
  • 群组