1. 传感器简介

DSOD705 是一款 非接触式水面溢油检测传感器,由地森合志 / DISEN 提供。设备基于 紫外荧光检测原理,通过向水面发射紫外脉冲,激发油类物质产生荧光,并通过光电接收与数据处理模块判断水面是否存在油污。

该传感器主要用于实时检测水面油污、漏油、溢油和浮油,可检测原油、柴油、燃料油、机油、润滑油、汽油、航空煤油等多种石油类物质。设备支持 RS-485 / Modbus RTU 输出,可通过 KC11 采集器接入 LoRaWAN 网络,再由 ThinkLink 平台完成数据解析、展示、告警和第三方系统转发。


2. 产品特点

DSOD705 的主要特点如下:

  1. 非接触式检测
    传感器安装在水面上方,无需直接接触被测水体,可减少油污附着、生物附着和人工清洗维护。
  2. 紫外荧光检测原理
    利用油类物质的天然荧光特性进行检测,适合识别水面石油类污染物。
  3. 高灵敏度
    可检测低至约 1 μm 厚度的油膜,适合早期溢油预警。
  4. 全天候在线监测
    支持 24 小时连续监测,不受白天或夜晚光照条件限制。
  5. RS-485 / Modbus RTU 输出
    便于接入工业现场采集系统、监控系统或通过 KC11 转换为 LoRaWAN 上报。
  6. 支持报警联动
    设备本体支持继电器输出,可用于本地报警或联动控制。
  7. 高防护等级
    说明书中描述设备具有 IP66/IP67 或 IP68 高防护能力,适合户外和复杂工业环境使用。
  8. 低功耗运行
    设备功耗低,说明书中标注直流功耗小于 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

(status & 0x02) === 0x02

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 逻辑说明:

  1. KC11 通过 RS-485 接口与 DSOD705 通信。
  2. 串口参数为 9600, 8N1,即 9600 bps、8 数据位、1 停止位、无校验。
  3. EB 逻辑使用 Modbus 功能码 0x04 读取输入寄存器。
  4. 读取地址范围为 0x0000 ~ 0x0001,共 2 个寄存器,用于解析一个 FloatLE 数据。
  5. 采集结果作为溢油检测值,通过 LoRaWAN Port 22 上报。
  6. 上传周期由 APP 参数地址 70 控制。
  7. 采集周期由 APP 参数地址 74 控制。
  8. COV 变化阈值由 APP 参数地址 110 控制。
  9. Modbus 从站地址由 APP 参数地址 150 控制。
  10. 业务代码为 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 工业传感器接入
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐