22107-DSOD705 溢油监测 通过EdgeBus 接入ThinkLink

1. 传感器简介
DSOD705 是一款 非接触式水面溢油检测传感器,由地森合志 / DISEN 提供。设备基于 紫外荧光检测原理,通过向水面发射紫外脉冲,激发油类物质产生荧光,并通过光电接收与数据处理模块判断水面是否存在油污。
该传感器主要用于实时检测水面油污、漏油、溢油和浮油,可检测原油、柴油、燃料油、机油、润滑油、汽油、航空煤油等多种石油类物质。设备支持 RS-485 / Modbus RTU 输出,可通过 KC11 采集器接入 LoRaWAN 网络,再由 ThinkLink 平台完成数据解析、展示、告警和第三方系统转发。
2. 产品特点
DSOD705 的主要特点如下:
- 非接触式检测
传感器安装在水面上方,无需直接接触被测水体,可减少油污附着、生物附着和人工清洗维护。 - 紫外荧光检测原理
利用油类物质的天然荧光特性进行检测,适合识别水面石油类污染物。 - 高灵敏度
可检测低至约 1 μm 厚度的油膜,适合早期溢油预警。 - 全天候在线监测
支持 24 小时连续监测,不受白天或夜晚光照条件限制。 - RS-485 / Modbus RTU 输出
便于接入工业现场采集系统、监控系统或通过 KC11 转换为 LoRaWAN 上报。 - 支持报警联动
设备本体支持继电器输出,可用于本地报警或联动控制。 - 高防护等级
说明书中描述设备具有 IP66/IP67 或 IP68 高防护能力,适合户外和复杂工业环境使用。 - 低功耗运行
设备功耗低,说明书中标注直流功耗小于 2 W,部分说明中也提到低功耗运行小于 10 W。
3. 适用范围
DSOD705 适用于工业与环境领域的水面油污在线监测,典型应用场景包括:
- 石油开采企业
- 船舶
- 海上平台
- 港口码头
- 石油化工厂
- 储油站、油库
- 电力站 / 发电厂
- 气体压缩站
- 污水处理厂
- 河道、湖泊
- 工业排水口
- 水环境安全监测场景
4. 采集器信息
4.1 硬件信息
本方案采用 KC11 作为 RS-485 数据采集与 LoRaWAN 接入设备。
|
项目 |
内容 |
|
采集设备型号 |
KC11 |
|
接口类型 |
RS-485 |
|
上行通信 |
LoRaWAN |
|
供电方式 |
220 V 供电 |
|
接入传感器 |
DSOD705 水面溢油检测传感器 |
|
协议 |
Modbus RTU |
|
默认串口参数 |
9600 bps,8 数据位,1 停止位,无校验 |
4.2 接线信息
电源与通讯接口
DSOD705 传感器线缆定义如下:
|
线色 |
功能 |
|
红色线 |
电源 +,+24 VDC |
|
黑色线 |
电源 -,GND |
|
黄绿色线 |
RS-485 A / 485_A |
|
白色线 |
RS-485 B / 485_B |
|
蓝色线 |
继电器 + |
|
绿色线 |
继电器 - |
|
棕色线 |
4-20 mA + |
|
灰色线 |
4-20 mA - |
|
裸露线 |
屏蔽层 |
本方案中主要使用以下接口:
|
DSOD705 |
KC11 / 外部电源 |
|
红色线 +24 V |
外部 24 VDC 电源正极 |
|
黑色线 GND |
外部 24 VDC 电源负极 |
|
黄绿色线 485_A |
KC11 RS-485 A |
|
白色线 485_B |
KC11 RS-485 B |
|
屏蔽层 |
建议接地或按现场 EMC 要求处理 |
传感器接口
本方案使用 DSOD705 的 RS-485 / Modbus RTU 接口进行数据采集。
4-20 mA 和继电器接口在本方案中不作为主要数据采集链路使用,可根据现场需求独立接入本地控制或报警系统。
5. 数据采集
本方案中,通过 Modbus 读取以下寄存器:
|
采集内容 |
功能码 |
起始地址 |
寄存器数量 |
数据类型 |
说明 |
|
传感器值 |
0x04 |
0x0000 |
2 |
Float,DCBA / Little Endian |
读取水面溢油检测值 |
KC11 通过 EdgeBus 逻辑周期性读取 DSOD705 的输入寄存器 0x0000 ~ 0x0001,读取结果按照 FloatLE 方式解析,并作为 oil 字段上报至 ThinkLink。
5.1 寄存器定义
只读寄存器
|
寄存器地址 |
长度 |
读写 |
数据类型 |
内容说明 |
|
0x0000 |
2 |
R |
Float(DCBA) |
读取传感器值 |
|
0x0001 |
2 |
R |
Float(DCBA) |
读取传感器温度 |
|
0x0010 |
6 |
R |
ASCII-HEX |
读取传感器 SN 值 |
|
0x0016 |
2 |
R |
HEX |
读取传感器硬件和软件版本 |
注:对接代码中实际读取的是 0x0000 ~ 0x0001,即读取 2 个寄存器组成一个浮点数,用于得到油污检测值。
保持寄存器
|
寄存器地址 |
长度 |
读写 |
数据类型 |
内容说明 |
|
0x0000 |
1 |
R/W |
Short |
读取 / 设置当前传感器地址,范围 1-247 |
|
0x0001 |
1 |
R/W |
Short |
波特率:0=4800,1=9600,2=19200,3=56000,4=57600,5=115200 |
|
0x0002 |
1 |
R/W |
Short |
检测间隔时间,单位 ms |
|
0x0006 |
2 |
R/W |
Float(DCBA) |
传感器到水面距离,单位 m |
|
0x0010 |
1 |
R/W |
Short |
继电器控制开关,0=关闭,1=开启 |
|
0x0012 |
2 |
R/W |
Float(DCBA) |
继电器控制最大值 |
|
0x0014 |
2 |
R/W |
Float(DCBA) |
继电器控制最小值 |
|
0x0016 |
2 |
R/W |
Float(DCBA) |
继电器动作延迟时间,单位 ms |
|
0x0020 |
1 |
R/W |
Short |
4-20 mA 输出模式 |
|
0x0022 |
2 |
R/W |
Float(DCBA) |
电流 4 mA 对应传感器值 |
|
0x0024 |
2 |
R/W |
Float(DCBA) |
电流 20 mA 对应传感器值 |
|
0x0026 |
1 |
R/W |
Short |
电流 4 mA 校准值,范围 7900-9900 |
|
0x0027 |
1 |
R/W |
Short |
电流 20 mA 校准值,范围 1700-3700 |
|
0x0030 |
2 |
R/W |
Float(DCBA) |
传感器 K 值 |
|
0x0032 |
2 |
R/W |
Float(DCBA) |
传感器 B 值 |
5.2 状态位定义
本方案中,EdgeBus / PayloadParser 会产生状态字段 status。当前脚本中使用以下状态判断:
|
状态位 |
判断方式 |
含义 |
|
bit1 |
|
Modbus 采集超时 |
当检测到超时状态时,物模型脚本会保留设备上一帧遥测数据,仅更新 status 状态字段,避免因本次采集超时导致平台侧业务数据被清空。
6. EdgeBus 模型
DSOD705 本身是 RS-485 / Modbus RTU 传感器,不是原生 LoRaWAN 设备,因此需要通过 KC11 内置 EdgeBus 逻辑完成 Modbus 采集和 LoRaWAN 上报。
6.1 EB 配置参数
|
参数 |
值 |
|
EB 名称 |
dsod705 |
|
LoRaWAN Port |
22 |
|
Version |
0x86 |
|
DataType |
0x07 |
|
业务代码 BzType |
22107 |
|
业务版本 BzVersion |
11 |
|
串口波特率 |
9600 |
|
数据位 |
8 |
|
停止位 |
1 |
|
校验位 |
NONE |
|
Modbus 功能码 |
0x04 |
|
Modbus 地址 |
保存于 APP 参数地址 150 |
|
上传周期参数 |
APP 参数地址 70 |
|
采集周期参数 |
APP 参数地址 74 |
|
COV 参数 |
APP 参数地址 110 |
|
采集寄存器 |
0x0000 ~ 0x0001 |
|
COV 类型 |
FloatLE |
参数说明:
- 上传周期和采集周期分开设置。
- 上传周期保存在 APP 参数地址
70。 - 采集周期保存在 APP 参数地址
74。 - 需要保证采集周期小于上传周期。
- COV 参数保存在 APP 参数地址
110。 - Modbus 地址保存在 APP 参数地址
150。
6.2 EB 代码
import {Buffer} from "buffer";
import {buildOtaFile} from "@EBSDK/run";
import {EBModel, EventInfoItem, LoraUpEvent, UpgrdTypeEnum, UserConfUPItem} from "@EBSDK/EBCompiler/all_variable";
import {CheckbitEnum, getOtaConfig, HwTypeEnum} from "@EBSDK/otaConfig";
////////////////////////////////////////////////////////////////////////////////////////
const eventInfo:UserConfUPItem[]=[
{
name:"dsod705",
port:22,
version:"0x86",
dataType:"0x07",
upPeriodIndex:70,
quInfo:[
{
protocol:"modbus",
code:"0x04",
periodIndex:74,
// addr:"0x01",
indexAPP:150,
indexCMD:0,
copySize:1,
isLast:false,
// period:"900s",
// payIndex:3,
// ackAddrIndex:0,
listVal:[
{
start: "0x0000",
end: "0x0001",
covType:"FloatLE",
covAppIndex:110
},
]
}
]
}
]
let otaConfig = getOtaConfig({
BaudRate: 9600,
StopBits: 1,
DataBits: 8,
Checkbit: CheckbitEnum.NONE,
Battery: false,
ConfirmDuty: 60,
BzType: 22107,
BzVersion: 11
})
const MODBUS_TT = (ebModel: EBModel) => {
for (let i=0; i<eventInfo.length; i++){
let event=new EventInfoItem(eventInfo[i]);
event.upEventSetup()
event.eventInstall()
}
return JSON.stringify(ebModel, null, 2)
}
6.3 说明
当前 EB 逻辑说明:
- KC11 通过 RS-485 接口与 DSOD705 通信。
- 串口参数为
9600, 8N1,即 9600 bps、8 数据位、1 停止位、无校验。 - EB 逻辑使用 Modbus 功能码
0x04读取输入寄存器。 - 读取地址范围为
0x0000 ~ 0x0001,共 2 个寄存器,用于解析一个 FloatLE 数据。 - 采集结果作为溢油检测值,通过 LoRaWAN Port 22 上报。
- 上传周期由 APP 参数地址
70控制。 - 采集周期由 APP 参数地址
74控制。 - COV 变化阈值由 APP 参数地址
110控制。 - Modbus 从站地址由 APP 参数地址
150控制。 - 业务代码为
22107,业务版本为11。
7. 物模型
7.1 物模型基本信息
数据物模型
|
项目 |
内容 |
|
名称 |
DSOD705 |
|
id Name |
dsod_22107 |
|
LoRaWAN Port |
22 |
|
数据长度 |
16 |
|
RSSI |
支持 |
|
电池字段 |
index 4 |
|
业务标识 Tag |
0x86 |
|
数据类型 Tag |
0x07 |
参数物模型
|
项目 |
内容 |
|
名称 |
DSOD705-PARA |
|
id Name |
dsod705_para_22107 |
|
参数上报 Port |
214 |
|
RPC 名称 |
dsod705_set_para_22107 |
7.2 上行帧结构
数据上行帧
|
字节位置 |
内容 |
|
index 0 |
Tag:0x86 |
|
index 1 |
Tag:0x07 |
|
index 4 |
Battery |
|
index 6 |
oil,FloatLE |
|
其他 |
EdgeBus 状态、RSSI 等辅助字段 |
数据字段定义:
|
字段名 |
field_name |
单位 |
index |
类型 |
系数 |
小数位 |
|
oil |
oil |
% |
6 |
floatLE |
1 |
2 |
参数字段定义
|
APP 参数地址 |
字段名 |
field_name |
单位 |
类型 |
说明 |
|
70 |
period_up |
period_up |
S |
uint32le |
上传周期 |
|
74 |
period_read |
period_read |
S |
uint32le |
采集周期 |
|
110 |
cov_oil |
cov_oil |
% |
floatLE |
溢油检测值 COV 阈值 |
|
150 |
addr_modbus |
addr_modbus |
uint8 |
Modbus 从站地址 |
7.3 物模型脚本
数据物模型脚本
let port = msg?.userdata?.port || null;
if (port != 22) return null
let frameInfo = {
port: 22,
dataLen: 16,
rssi: true,
battery: 4,
tagList: [
{ index: 0, tag: 0x86 },
{ index: 1, tag: 0x07 }
]
}
let appInfo = [
{
name: "oil",
field_name: "oil",
unit: "%",
index: 6,
type: "floatLE",
coefficient: 1,
decimal: 2
},
]
let payParser = new PayloadParser({
device: device,
msg: msg,
frameInfo: frameInfo,
appInfo: appInfo,
})
let tdata = payParser.telemetry()
if (tdata == undefined) {
return null
}
if ((tdata?.status & 0x02) === 0x02) { // time out, just update the status.
const status = tdata.status
tdata = { ...(device.telemetry_data?.[thingModelId] ?? {}) }
tdata.status = status
}
return {
telemetry_data: tdata,
server_attrs: null,
shared_attrs: null
}
参数物模型脚本
let port = msg?.userdata?.port || null;
const rpcName = "dsod705_set_para_22107";
let paraDef = {
app_70: {
name: "period_up",
field_name: "period_up",
unit: "S",
type: "uint32le"
},
app_74: {
name: "period_read",
field_name: "period_read",
unit: "S",
type: "uint32le"
},
app_110: {
name: "cov_oil",
field_name: "cov_oil",
unit: "%",
type: "floatLE",
decimal: 1
},
app_150: {
name: "addr_modbus",
field_name: "addr_modbus",
unit: "",
type: "uint8"
}
}
if (port !== 214) {
let checkData = Utils.paraCheck(rpcName, device.server_attrs, device.shared_attrs)
return {
server_attrs: checkData.sdata,
action: checkData.action,
}
}
let pdata = (new PayloadParser({
device: device,
msg: msg,
paraInfo: paraDef,
})).paras()
let checkData = Utils.paraCheck(rpcName, pdata)
return {
telemetry_data: pdata,
server_attrs: checkData.sdata,
shared_attrs: pdata,
action: checkData.action,
}
8. 第三方平台数据订阅
8.1 MQTT Topic
/v32/{Organization Account}/tkl/up/telemetry/{eui}
8.2 上报示例数据
{
"eui": "6353012af10a9331",
"active_time": "2026-02-05T08:35:48.000Z",
"thingModelId": "dsod_22107",
"thingModelIdName": "DSOD705",
"telemetry_data": {
"snr": 13.5,
"rssi": -51,
"battery": 3.37,
"oil": 12.34,
"status": 0
}
}
字段说明:
|
字段 |
含义 |
|
eui |
LoRaWAN 终端 EUI |
|
active_time |
数据上报时间 |
|
thingModelId |
物模型 ID |
|
thingModelIdName |
物模型名称 |
|
snr |
LoRaWAN 信噪比 |
|
rssi |
LoRaWAN 信号强度 |
|
battery |
设备电池 / 电源状态字段 |
|
oil |
DSOD705 溢油检测值,单位 % |
|
status |
EdgeBus / Modbus 采集状态 |
9. RPC
9.1 RPC 名称
本方案包含两个 RPC:
|
RPC 功能 |
名称 |
id Name |
|
设置参数 |
DSOD705 SET para |
dsod705_set_22107 |
|
读取参数 |
DSOD705 GET para |
dsod705_get_22107 |
其中设置参数使用的内部 RPC 名称为:
dsod705_set_para_22107
9.2 参数定义
|
参数 |
field_name |
APP 地址 |
单位 |
类型 |
说明 |
|
period_up |
period_up |
70 |
S |
uint32le |
上传周期 |
|
period_read |
period_read |
74 |
S |
uint32le |
采集周期 |
|
cov_oil |
cov_oil |
110 |
% |
floatLE |
油污检测值 COV 阈值 |
|
addr_modbus |
addr_modbus |
150 |
uint8 |
Modbus 从站地址 |
参数设置建议:
period_read应小于period_up。addr_modbus应与 DSOD705 传感器实际 Modbus 地址一致。cov_oil用于控制油污检测值变化上报阈值,可根据现场油污检测灵敏度需求配置。
9.3 RPC 代码
设置参数 RPC
let classMode = (device && device.shared_attrs && device.shared_attrs.class_mode) || "ClassA";
const rpcName = "dsod705_set_para_22107"
let paraDef = {
app_70: {
name: "period_up",
field_name: "period_up",
unit: "S",
type: "uint32le"
},
app_74: {
name: "period_read",
field_name: "period_read",
unit: "S",
type: "uint32le"
},
app_110: {
name: "cov_oil",
field_name: "cov_oil",
unit: "%",
type: "floatLE",
decimal: 1
},
app_150: {
name: "addr_modbus",
field_name: "addr_modbus",
unit: "",
type: "uint8"
}
}
let frames = RPCHelper.buildFrame({
paraDef: paraDef,
params: params
});
let redoBuffer = RPCHelper.redo()
let dnBuffer = Buffer.alloc(frames.writeBuffer.length + frames.readBuffer.length);
frames.writeBuffer.copy(dnBuffer, 0)
frames.readBuffer.copy(dnBuffer, frames.writeBuffer.length)
logger.info("set para")
let msgQue = Utils.makeParaSetMSG({
device: device,
classMode: classMode,
rpcName: rpcName,
params: params,
paraDownBuffer: dnBuffer,
extraAppBuffer: redoBuffer
})
if (msgQue.length == 0) return null
return msgQue
读取参数 RPC
let paraDef = {
app_70: {
name: "period_up",
field_name: "period_up",
unit: "S",
type: "uint32le"
},
app_74: {
name: "period_read",
field_name: "period_read",
unit: "S",
type: "uint32le"
},
app_110: {
name: "cov_oil",
field_name: "cov_oil",
unit: "%",
type: "floatLE",
decimal: 1
},
app_150: {
name: "addr_modbus",
field_name: "addr_modbus",
unit: "",
type: "uint8"
}
}
let frames = RPCHelper.buildFrame({
paraDef: paraDef,
params: params
});
let msg = RPCHelper.makeMSG({
msgType: Utils.msgType.paras,
device: device,
dnBuffer: frames.readBuffer,
sleepTime: 0,
})
return [msg]
10. 模板选择
在 ThinkLink 平台中搜索模板:
DSOD705
或搜索物模型 id Name:
dsod_22107
参数物模型可搜索:
dsod705_para_22107
RPC 可搜索:
dsod705_set_22107
dsod705_get_22107
或按业务类型查找:
水面溢油检测
非接触式溢油检测
RS-485 溢油传感器
Modbus RTU 水质 / 环境监测
LoRaWAN 工业传感器接入
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)