数据接入驱动开发
本文将会详细介绍如何使用 Python SDK
开发自定义数据接入驱动. 示例项目目上传至 https://github.com/air-iot/sdk-python-examples/tree/master/driver.
介绍
数据接入驱动
是为实现从不同的协议、设备或其它平台系统采集数据而开发的特定程序. 每个 数据接入驱动
程序需要根据协议的特点实现数据采集功能,然后将采集到的数据通过 Python SDK
提供的接口发送到平台.
Python SDK
提供了 数据接入驱动
开发的相关内容. 包括驱动的接口定义, 以及与平台交互功能. 开发者只需要在项目中引入 airiot_python_sdk
依赖, 定义配置信息(schema及配置类),然后实现 DriverApp
接口中的方法即可.
开发步骤
1. 创建项目
数据接入驱动开发, 对项目结构未做要求, 根据自己的习惯创建项目即可. 使用的 Python
版本见 版本说明.
2. 引入SDK
驱动二次开发相关内容都在 driver
子包内.
3. 定义schema
数据接入驱动
需要定义一个 schema
用于描述驱动的配置信息. schema
是一个类似于 json
格式的对象, 详细格式说明见 数据接入驱动schema说明. 以下是一个简单的示例:
({
"driver": {
"properties": {
"settings": {
"title": "模型配置",
"type": "object",
"properties": {
"server": {
"type": "string",
"title": "MQTT Broker",
"descripption": "MQTT 服务器地址. 例如: tcp://127.0.0.1:1883"
},
"username": {
"type": "string",
"title": "用户名",
},
"password": {
"type": "string",
"title": "密码",
"fieldType": "password"
},
"network": {
"type": "object",
"title": "通讯监控参数",
"properties": {
"timeout": {
"title": "通讯超时时间(s)",
"description": "经过多长时间仪表还没有任何数据上传,认定为通讯故障",
"type": "number"
}
},
"form": [{
"key": "timeout",
}]
}
},
"required": ["server", "username", "password"]
},
"tags": {
"title": "数据点",
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"title": "Key",
"description": "数据点在 JSON 对象中的 Key. 例如: 'temperature'",
},
},
"required": ["key"]
}
},
"commands": {
"title": "命令",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "名称"
},
"ops": {
"type": "array",
"title": "指令",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "主题",
"description": "发送消息的主题. 例如: /cmd/control",
},
"message": {
"type": "string",
"title": "消息",
"description": "发送的消息. 例如: {\"cmd\":\"start\"}",
},
"qos": {
"type": "number",
"title": "QoS",
"description": "消息质量. 0,1,2",
"enum": ["0", "1", "2"],
"enum_title": ["QoS0", "QoS1", "QoS2"]
},
},
"required": ["name", "message"]
}
}
}
}
}
}
},
"model": {
"properties": {
"settings": {
"title": "模型配置",
"type": "object",
"properties": {
"topic": {
"type": "string",
"title": "主题",
"descripption": "接收数据的主题. 例如: /data/#"
},
"parseScript": {
"type": "string",
"title": "数据处理脚本",
"fieldType": "deviceScriptEdit",
"description": "消息处理脚本. 函数名必须为 'handler'",
"defaultScript": "/**\n" +
" * 数据处理脚本, 处理从 mqtt 接收到的数据.\n" +
" *\n" +
" * @param {string} topic 消息主题\n" +
" * @param {string} message 消息内容\n" +
" * @return 消息解析结果\n" +
" */\n" +
"function handler(topic, message) {\n" +
"\t\n" +
"\t// 脚本返回值必须为对象数组\n" +
"\t// \tid: 资产编号\n" +
"\t//\ttime: 时间戳(毫秒)\n" +
"\t// fields: 数据点数据. 该字段为 JSON 对象, key 为数据点标识, value 为数据点的值\n" +
"\treturn [\n" +
"\t\t{\"id\": \"SN10001\", \"time\": new Date().getTime(), \"fields\": {\"key1\": \"this is a string value\", \"key2\": true, \"key3\": 123.456}}\n" +
"\t];\n" +
"}"
},
"commandScript": {
"type": "string",
"title": "指令处理脚本",
"fieldType": "deviceScriptEdit",
"description": "指令处理脚本. 函数名必须为 'handler'",
"defaultScript": "/**\n" +
" * 指令处理脚本. 发送指令时会将指令内容传递给脚本, 然后由指定返回最终要发送的信息.\n" +
" *\n" +
" * @param {string} 工作表标识\n" +
" * @param {string} 资产编号\n" +
" * @param {object} 命令内容\n" +
" * @return {object} 最终要发送的消息, 及目标 topic\n" +
" */\n" +
"function handler(tableId, deviceId, command) {\n" +
"\t\n" +
"\t// 脚本返回值必须为下面对象结构\n" +
"\t//\t\ttopic: 消息发送的目标 topic\n" +
"\t//\t\tpayload: 消息内容\n" +
"\treturn {\n" +
"\t\t\"topic\": \"cmd/\" + deviceId,\n" +
"\t\t\"payload\": \"发送内容\"\n" +
"\t};\n" +
"}"
},
"network": {
"type": "object",
"title": "通讯监控参数",
"properties": {
"timeout": {
"title": "通讯超时时间(s)",
"description": "经过多长时间仪表还没有任何数据上传,认定为通讯故障",
"type": "number"
}
},
"form": [{
"key": "timeout",
}]
}
},
"required": ["server", "username", "password", "topic"]
},
"tags": {
"title": "数据点",
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"title": "Key",
"description": "数据点在 JSON 对象中的 Key. 例如: 'temperature'",
},
},
"required": ["key"]
}
},
"commands": {
"title": "命令",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "名称"
},
"ops": {
"type": "array",
"title": "指令",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "主题",
"description": "发送消息的主题. 例如: /cmd/control",
},
"message": {
"type": "string",
"title": "消息",
"description": "发送的消息. 例如: {\"cmd\":\"start\"}",
},
"qos": {
"type": "number",
"title": "QoS",
"description": "消息质量. 0,1,2",
"enum": ["0", "1", "2"],
"enum_title": ["QoS0", "QoS1", "QoS2"]
},
},
"required": ["name", "message"]
}
}
}
}
}
}
},
"device": {
"properties": {
"settings": {
"title": "设备配置",
"type": "object",
"properties": {
"customDeviceId": {
"type": "string",
"title": "设备编号",
"descripption": "自定义设备编号. 如果未定义则使用平台中的资产编号"
},
"network": {
"type": "object",
"title": "通讯监控参数",
"properties": {
"timeout": {
"title": "通讯超时时间(s)",
"description": "经过多长时间仪表还没有任何数据上传,认定为通讯故障",
"type": "number"
}
}
}
},
"required": []
}
}
}
})
4. 实现驱动接口
数据接入驱动二次开发SDK中, 有两个重要接口: 数据接入驱动接口
和 驱动与平台交互接口
, 分别为 DriverApp 和 DataSender.
数据接入驱动接口(DriverApp) 该接口中定义平台控制驱动程序运行的相关方法, 是平台控制驱动程序的入口.
SDK
在驱动程序启动后, 会监听平台下发的控制指令, 然后调用数据接入驱动接口
中的方法并将执行结果返回给平台. 开发者需要实现这个接口, 并提供一个工厂类DriverAppFactory
, 并且将工厂类传递给驱动启动器Launcher
. 接口定义及详细说明见 数据接入驱动接口说明.驱动与平台交互接口(DataSender) 是驱动程序与平台进行交互的接口. 驱动程序在运行过程中, 除了接收平台的控制之外, 也需要与平台进行各种交互. 例如: 向平台发送采集的到数据, 向平台发送指令执行结果、调试日志等.
SDK
中定义了驱动与平台交互接口
DataSender 以及实现类, 该实现类会通过工厂类方法传入, 可以在工厂类方法中创建DriverApp
时保存该对象. 接口定义及详细说明见 驱动与平台交互接口说明.
注: 向平台上报采集到的数据时, 必须通过 驱动与平台交互接口
中的 writePoint
方法发送, 不能直接调用 MQTT
客户端发送. 因为 SDK
会对发送的数据进行一些处理, 包括有效范围处理、数值映射、缩放比例、小数位等处理.
:::
5. 配置驱动
这里所说 驱动配置
主要是一些静态配置信息(与 schema 中定义的配置无关), 其中包括 平台配置信息
, 驱动配置信息
和 自定义配置信息
. 这些信息一般通过配置文件(application.yml)、环境变量、命令行参数等方式传入. 其中一些配置信息由平台启动驱动时通过命令行参数传入.
这些配置信息, 在开发过程中可以根据实际情况进行调整. 但是在打包时必须按照平台的要求进行配置. 打包时的配置信息见 驱动配置说明.
自定义配置信息
是指驱动本身的一些配置信息, 对驱动使用者不可见. 例如: 连接池大小. 这些信息一般通过配置文件(application.yml)、环境变量、命令行参数等方式传入.
平台配置信息
平台配置信息
主要为平台的连接信息. 包括: MQTT
连接信息, 驱动管理服务
连接信息. 内容如下:
# 驱动管理服务配置信息
driver-grpc:
# 在开发时, 需要配置为平台的地址
host: 192.168.11.101
# 端口默认为 9224, 一般无须修改. 如果有修改, 可在运维管理系统中查看 `driver` 服务的端口号
port: 9224
# 平台 MQTT 配置信息
mq:
mqtt:
# 在开发时, 需要配置为平台的地址
host: 192.168.11.101
port: 1883
username: admin
password: public
# 如果驱动对外提供 web 接口服务, 则需要按以下方式配置 web 服务的端口号
server:
port: 8080
相关服务的端口号可在运维管理系统中查看.
平台中的 driver
服务的端口对应 driver-grpc.port
配置项, mqtt
服务的端口对应 mq.mqtt.port
配置项.
驱动配置信息
驱动配置信息
主要包括 驱动ID
, 驱动名称
, 驱动实例ID
, 所属项目ID
.
驱动ID
为驱动的唯一标识, 必须在平台中唯一.驱动名称
为该驱动在平台中的显示名称.驱动实例ID
为该驱动实例的唯一标识. 同一个驱动可以创建多个实例, 每个实例的驱动ID
相同但驱动实例ID
唯一. 该信息由平台在驱动管理
中创建驱动实例时生成.所属项目ID
每个驱动实例都属于一个项目, 该驱动实例只会拿到该项目中的模型和设备信息.
id: 驱动ID
name: 驱动名称
驱动ID
和驱动名称
需要在config.yml
中手动定义.驱动实例ID
和所属项目ID
在开发过程中, 需要将这些信息手动配置到application.yml
中. 在打包时无须定义, 在平台中安装驱动时这些信息会由平台通过命令行参数传入.
示例配置
id: python_sdk_demo_driver
name: PythonSDK示例驱动
# 驱动管理服务配置信息
driver-grpc:
# 在开发时, 需要配置为平台的地址
host: 192.168.11.101
# 端口默认为 9224, 一般无须修改. 如果有修改, 可在运维管理系统中查看 `driver` 服务的端口号
port: 9224
# 平台 MQTT 配置信息
mq:
mqtt:
# 在开发时, 需要配置为平台的地址
host: 192.168.11.101
port: 1883
username: admin
password: public
# 如果驱动对外提供 web 接口服务, 则需要按以下方式配置 web 服务的端口号
server:
port: 8080
6. 打包
驱动打包就是将开发完成的程序打包为可以在平台部署的驱动. 平台自身支持运行在 windows
、linux
和 macOS
系统中, 并且支持 x86
和 arm
平台.
在 windows
系统中平台服务和驱动程序都是直接运行在操作系统中, 而在 linux
系统中是以 容器
的方式运行, 平台中的每个服务和驱动程序都是一个独立的容器, 所以针对不同的操作系统打包方式也不相同. 下面分别介绍在 windows
和 linux
系统中如何打包驱动, 对于不同平台只需要保证使用软件和库支持即可.
windows系统打包
将程序和相关资源打包. 可以使用
PyInstaller
等工具将程序打包为可执行文件, 或者直接使用python main.py
等方式运行程序. 注: 使用python main.py
的方式运行程序时, 需要将python
运行环境一起打包准备驱动配置文件
config.yml
. 可以将config.yml
文件放在根目录下, 或放在其它目录中, 然后在程序中加载.
注: config.yml
中需要填写好 驱动ID
和 驱动名称
两个配置项.
- 准备驱动安装配置文件
service.yml
. 在平台中安装驱动时, 需要提供一些驱动的基本信息, 例如: 版本号、驱动描述、端口号等. 这些信息需要在service.yml
中定义, 平台会根据该文件中的配置信息进行安装.service.yml
的具体格式如下:
# 必填项. 驱动名称
Name: python_sdk_demo_driver
# 非必填项. 如果驱动对外提供 rest 服务, 则需要填写 rest 接口的统一路径前缀.
# 当填写该配置项时, 平台会自动在网关中添加该路径的路由, 并将请求转发到该驱动, 代理端口为 service.yml 文件中的 server.port 配置项.
Path: /python_sdk_demo_driver
# 必填项. 例如: 1.0.0
Version: 1.0.0
# 非必填项.
Description: 驱动描述信息
# 驱动的配置文件名称, 平台在创建驱动时会查找驱动打包文件中查找该文件. 一般固定填写 service.yml
ConfigType: service.yml
# 必填项. 固定为 driver
GroupName: driver
# 必填项. 驱动启动命令. 还可以添加一些启动参数
# 如果使用 PyInstaller 工具打包, 直接运行打包后的可执行文件即可.
# 例如, 打包后的可执行文件名为 my-program.exe, 直接填写 Command: my-program.exe [args...]
Command: python main.py
- 将所有资源打包为
zip
文件.
将项目中的源码或打包后的文件、config.yml
、service.yml
和其它资源打包为 zip
文件, 平台会根据该文件进行安装. 建议打包后的 zip
文件结构如下:
linux系统打包
由于在 linux
系统中, 驱动程序是以 容器
的方式运行, 所以打包时需要先将驱动程序打包为 docker
镜像. 然后再将镜像文件和 service.yml
打包为 .tar.gz
压缩包. 具体打包步骤如下:
将程序和相关资源打包. 可以使用
PyInstaller
等工具将程序打包为可执行文件, 或者直接使用带有python
运行环境的镜像作为基础镜像进行构建自己的镜像. 注: 使用python main.py
的方式运行程序时, 需要将python
运行环境一起打包准备
Dockerfile
文件. 以下是一个简单的Dockerfile
文件示例, 具体内容根据自身的需求进行修改:
# 根据自身的需求选择合适的基础镜像
FROM python:3.10.12-alpine
WORKDIR /app
# 如果驱动配置文件在 jar 文件外面
COPY config.yml /app/
# 复制 jar 文件
COPY main.py /app/main.py
# 启动命令, 根据自身的需求添加启动参数
# 注: 必须使用 ENTRYPOINT 启动程序
ENTRYPOINT ["python", "main.py"]
- 构建
docker
镜像.
使用上一步中的 Dockerfile
文件构建 docker
镜像, 具体命令如下:
docker build -t myDriver:1.0.0 .
- 导出
docker
镜像并压缩.
docker save myDriver:1.0.0 | gzip > myDriver.tar.gz
- 准备驱动安装配置文件
service.yml
. 该文件的格式与 windows系统打包 中的第三步中的service.yml
文件格式相似但又有区别. 具体格式如下:
# 必填项. 驱动名称
Name: python_sdk_demo_driver
# 非必填项. 如果驱动对外提供 rest 服务, 则需要填写 rest 接口的统一路径前缀.
# 当填写该配置项时, 平台会自动在网关中添加该路径的路由, 并将请求转发到该驱动, 代理端口为 application.yml 文件中的 server.port 配置项.
Path: /python_sdk_demo_driver
# 必填项. 例如: 1.0.0, 通常用镜像版本号一致
Version: 1.0.0
# 非必填项.
Description: 驱动描述信息
# 必填项. 固定为 driver
GroupName: driver
# 容器端口映射类型, 非必填项. 如果驱动需要对外提供 rest 服务, 或暴露端口时, 需要填写该配置项.
# 可选项有 None Internal External
#
# None: 不暴露端口
# Internal: 只在平台内部暴露端口. 一般为驱动对外提供 rest 服务时, 将端口映射到网关上, 填写为 Internal 即可.
# External: 对外暴露端口. 一般为驱动为作 server 端, 需要对外暴露端口以供设备连接, 此时该端口会暴露在宿主机上, 填写为 External 即可.
Service: Internal
# 非必填项. 暴露的端口列表
Ports:
- Host: "8558" # 映射到宿主机的端口号, 如果不填写, 则会随机分配一个端口号
Container: "8558" # 容器内部的端口号, 即驱动服务监听的端口号
Protocol: "" # 协议类型, 可选项有 TCP UDP, 如果不填写, 则默认为 TCP
- 将所有资源打包为
gzip
文件. 将docker镜像
和service.yml
文件打包为gzip
文件. 打包命令如下:
tar czvf myDriver-linux.tar myDriver.tar service.yml
打包后的 gzip
文件结构如下:
linux
系统整个打包过程对应的命令如下所示:
# 将驱动打包为镜像
docker build -t myDriver:1.0.0 .
# 导出镜像并压缩
docker save myDriver:1.0.0 | gzip > myDriver.tar.gz
# 将镜像文件和 service.yml 打包
tar czvf myDriver-linux.tar myDriver.tar.gz service.yml
# 最后得到 myDriver-linux.tar.gz 压缩文件
7. 部署
将上一步骤中得到的驱动安装包通过 运维管理系统
上传到平台, 平台会自动解析并安装驱动. 安装成功后, 就可以在项目中使用该驱动了.
安装驱动
- 登录
运维管理系统
, 运维管理系统的默认登录地址为http://IP:13030/
, 将IP
换成平台地址即可. - 点击左侧菜单栏中的
服务管理
选项, 进入服务管理页面. - 点击页面右上角的
离线上传驱动
按钮, 选择上一步中得到的myDriver-linux.tar.gz
文件, 点击确定
按钮, 平台会自动解析并安装驱动.
如果驱动安装失败, 可以在 运维管理系统
的 首页
中查看详细的日志信息.
不同版本的平台, 离线上传驱动
按扭的位置可能不同.
使用驱动
当驱动成功安装到平台后, 就可以在项目中使用该驱动了.
具体使用方法请参考 驱动管理.
数据接入驱动接口说明
驱动接口定义
class DriverApp:
"""
驱动程序接口. 该接口定义驱动程序与平台交互的方法. 所有驱动程序都需要实现该接口.
"""
@abstractmethod
def get_version(self) -> str:
"""
获取驱动版本号. 例如: v4.0.0
:return: 驱动版本号
"""
pass
@abstractmethod
def http_proxy_enabled(self) -> bool:
"""
是否启用 HTTP 请求代理. 用于代理驱动中的 HTTP 请求, 可以将驱动中的一些功能通过 grpc 代理暴露给平台, 由平台代理驱动中的 HTTP 请求.
:return: 是否启用 HTTP 请求代理. 返回 False 表示不启用, 返回 True 表示启用.
"""
return False
@abstractmethod
async def http_proxy(self, request_type: str, headers: dict[str, List[str]], data: str) -> any:
"""
HTTP 请求代理. 用于代理驱动中的 HTTP 请求, 例如: 获取设备数据, 获取设备属性, 控制设备等.\r\n
当前端请求驱动时, 会将请求转发给平台的 driver 服务, 由 driver 服务通过 listener 协议转发到驱动中, 由驱动自行处理请求并返回响应结果.\r\n
前端 <- http -> driver <- listener -> DriverApp
:param request_type: 请求类型标识, 每个请求类型标识对应一个请求. 例如: getDevices 表示查询设备列表请求.
:param headers: 请求头, 即前端请求时传递的 headers.
:param data: 请求参数.
:return: 请求响应结果
"""
pass
@abstractmethod
async def start(self, config: str):
"""
启动驱动. 当驱动程序启动时, SDK 会连接平台 driver 服务, 连接成功后会调用此方法.
:param config: 驱动配置, 即使用该驱动实例的工作表、设备等信息.
:return:
"""
pass
@abstractmethod
async def stop(self):
"""
停止驱动. 当驱动程序停止时, SDK 会断开平台 driver 服务的连接, 断开连接后会调用此方法.
:return:
"""
pass
@abstractmethod
async def run(self, serial_no: str, table_id: str, device_id: str, command: str) -> any:
"""
执行设备命令. 当前端需要控制设备时, 会调用此方法.
:param serial_no: 平台指令序列号, 每次发送指令时, 平台会生成一个唯一的序列号, 用于标识本次指令.
:param table_id: 设备所属工作表 ID.
:param device_id: 设备编号.
:param command: 指令内容.
:return: 指令执行结果
"""
pass
@abstractmethod
async def batch_run(self, serial_no: str, table_id: str, device_ids: List[str], command: str) -> any:
"""
批量执行设备命令. 当前端需要控制多个设备时, 会调用此方法.
:param serial_no: 平台指令序列号, 每次发送指令时, 平台会生成一个唯一的序列号, 用于标识本次指令.
:param table_id: 设备所属工作表 ID.
:param device_ids: 设备编号列表.
:param command: 指令内容.
:return: 指令执行结果
"""
pass
@abstractmethod
async def write_tag(self, serial_no: str, table_id: str, device_id: str, tag: str) -> any:
"""
向设备的指定数据点写入数据. 只有数据点的 rw 为 true 的数据点, 才能被写入数据.
:param serial_no: 平台指令序列号, 每次发送指令时, 平台会生成一个唯一的序列号, 用于标识本次指令.
:param table_id: 设备所属工作表 ID.
:param device_id: 设备编号列表.
:param tag: 数据点信息及写入的值.
:return: 指令执行结果
"""
pass
@abstractmethod
async def debug(self, debug: str) -> str:
"""
驱动调试. 当前端需要调试驱动时, 会调用此方法.(该方法暂未开放)
:param debug: 调试内容.
:return: 调试结果
"""
pass
@abstractmethod
async def schema(self) -> str:
"""
获取驱动的 schema. 当前端需要获取驱动的 schema 时, 会调用此方法.
:return: 驱动的 schema 定义
"""
工厂类定义
class DriverAppFactory:
"""
驱动程序实例构造工厂接口. 该接口定义驱动程序实例构造工厂的方法. 所有驱动程序实例构造工厂都需要实现该接口.
"""
def create(self, service_id: str, data_sender: DataSender) -> DriverApp:
"""
驱动程序实例构造工厂
:param service_id: 驱动实例ID
:param data_sender: 数据发送器
:return: 驱动程序实例
"""
pass
示例
class MyDriverApp(DriverApp):
"""
驱动程序类
"""
class MyDriverAppFactory(DriverAppFactory):
"""
驱动实例构造工厂
"""
def create(self, service_id: str, data_sender: DataSender) -> DriverApp:
return MyDriverApp()
驱动与平台交互接口说明
class DataSender:
"""
数据发送器, 用于向平台发送数据
"""
async def write_point(self, point: Point):
"""
向平台发送设备采集到的数据
:param point: 设备采集到的数据
:return:
:raise ValueError: point is None
"""
pass
def write_event(self, event: Event) -> Response:
"""
向平台发送事件信息
:param event: 事件信息
:return: 事件发送结果
:raises ValueError: event is None
"""
pass
def update_table_data(self, table_id: str, device_id: str, fields: dict[str, any]) -> Response:
"""
更新设备数据
:param table_id: 设备所属工作表标识
:param device_id: 设备编号
:param fields: 更新的字段信息. key 为字段名, value 为字段值.
:return: 设备信息修改结果
:raise ValueError: the table_id, device_id or fields is None or empty
"""
pass
def write_run_log(self, log: RunLog) -> Response:
"""
向平台发送指令执行日志
:param log: 执行日志
:return: 日志发送结果
:raise ValueError: log is None
"""
pass
def log_debug(self, table_id: str, device_id: str, message: str):
"""
发送 DEBUG 日志. 该日志信息可以在 "设备配置" 中的 "设备调试" 面板中查看.
:param table_id: 设备所属工作表标识
:param device_id: 设备编号
:param message: 日志内容
:return:
"""
pass
def log_info(self, table_id: str, device_id: str, message: str):
"""
发送 INFO 日志. 该日志信息可以在 "设备配置" 中的 "设备调试" 面板中查看.
:param table_id: 设备所属工作表标识
:param device_id: 设备编号
:param message: 日志内容
:return:
"""
pass
def log_warn(self, table_id: str, device_id: str, message: str):
"""
发送 WARN 日志. 该日志信息可以在 "设备配置" 中的 "设备调试" 面板中查看.
:param table_id: 设备所属工作表标识
:param device_id: 设备编号
:param message: 日志内容
:return:
"""
pass
def log_error(self, table_id: str, device_id: str, message: str):
"""
发送 ERROR 日志. 该日志信息可以在 "设备配置" 中的 "设备调试" 面板中查看.
:param table_id: 设备所属工作表标识
:param device_id: 设备编号
:param message: 日志内容
:return:
"""
pass
驱动配置说明
以下是完整的驱动配置文件, 请参考该配置文件进行配置.
id: python_sdk_demo_driver # 驱动ID
name: PythonSDK示例驱动 # 驱动名称
# 驱动管理服务配置信息
driver-grpc:
# 在开发时, 需要配置为平台的地址
host: 192.168.11.101
# 端口默认为 9224, 一般无须修改. 如果有修改, 可在运维管理系统中查看 `driver` 服务的端口号
port: 9224
# 平台 MQTT 配置信息
mq:
mqtt:
# 在开发时, 需要配置为平台的地址
host: 192.168.11.101
port: 1883
username: admin
password: public
# 如果驱动对外提供 web 接口服务, 则需要按以下方式配置 web 服务的端口号
server:
port: 8080
windows系统打包发布时的驱动配置
id: python_sdk_demo_driver
name: PythonSDK示例驱动
driver-grpc:
host: 127.0.0.1
port: 9224
mq:
mqtt:
host: 127.0.0.1
port: 1883
username: admin
password: public
server:
port: 8080
linux系统打包发布时的驱动配置
id: python_sdk_demo_driver
name: PythonSDK示例驱动
driver-grpc:
host: driver
port: 9224
mq:
mqtt:
host: mqtt
port: 1883
username: admin
password: public
server:
port: 8080