Skip to content

1. Sensor Overview

Model catalog

Search for these models in ThinkLink by name or ID.

Model typeNameid_namePlatform model ID
RPC[DSOD705 GET] paradsod705_get_22107100637692055785477
RPC[DSOD705 SET] paradsod705_set_22107100638082046365701
TemplateDSOD705-22107100638935071330309
Parameter Thing Model[DSOD705-PARA]dsod705_para_22107100632408214212613
Thing Model[DSOD705]dsod_22107100631632184086533
Thing Model[DSOD-22107-DSOD705资产] 区域聚合dsod_asset_22107119677174411063306

The DSOD705 is a non-contact water surface oil spill detection sensor provided by DISEN. The device is based on the ultraviolet fluorescence detection principle. It emits ultraviolet pulses toward the water surface, excites oil substances to generate fluorescence, and determines whether oil contamination exists on the water surface through photoelectric reception and data processing.

This sensor is mainly used for real-time detection of oil pollution, oil leakage, oil spills, and floating oil on water surfaces. It can detect various petroleum-based substances, including crude oil, diesel, fuel oil, engine oil, lubricating oil, gasoline, aviation kerosene, and more.

The device supports RS-485 / Modbus RTU output. It can be connected to a LoRaWAN network through the KC11 data collector, and the ThinkLink platform can then perform data parsing, visualization, alarm processing, and forwarding to third-party systems.


2. Product Features

The main features of the DSOD705 are as follows:

1. Non-contact detection

The sensor is installed above the water surface and does not need to directly contact the measured water body. This helps reduce oil adhesion, biofouling, and manual cleaning maintenance.

2. Ultraviolet fluorescence detection principle

The sensor uses the natural fluorescence characteristics of oil substances for detection, making it suitable for identifying petroleum pollutants on water surfaces.

3. High sensitivity

It can detect oil films with a thickness as low as approximately 1 μm, making it suitable for early oil spill warning.

4. All-weather online monitoring

The sensor supports continuous 24-hour monitoring and is not affected by daytime or nighttime lighting conditions.

5. RS-485 / Modbus RTU output

It can be easily connected to industrial data acquisition systems, monitoring systems, or converted to LoRaWAN reporting through KC11.

6. Alarm linkage support

The device itself supports relay output, which can be used for local alarms or linkage control.

7. High protection rating

According to the manual, the device has high protection capability such as IP66/IP67 or IP68, making it suitable for outdoor and complex industrial environments.

8. Low-power operation

The device has low power consumption. The manual indicates that DC power consumption is less than 2 W, while some descriptions also mention low-power operation below 10 W.


3. Application Scope

The DSOD705 is suitable for online water surface oil pollution monitoring in industrial and environmental applications. Typical application scenarios include:

  • Oil production enterprises
  • Ships
  • Offshore platforms
  • Ports and terminals
  • Petrochemical plants
  • Oil storage stations and oil depots
  • Power stations / power plants
  • Gas compressor stations
  • Wastewater treatment plants
  • Rivers and lakes
  • Industrial drainage outlets
  • Water environment safety monitoring scenarios

4. Data Collector Information

4.1 Hardware Information

This solution uses KC11 as the RS-485 data acquisition and LoRaWAN access device.

ItemDescription
Data acquisition device modelKC11
Interface typeRS-485
Uplink communicationLoRaWAN
Power supply220 V power supply
Connected sensorDSOD705 water surface oil spill detection sensor
ProtocolModbus RTU
Default serial port parameters9600 bps, 8 data bits, 1 stop bit, no parity

4.2 Wiring Information

Power and Communication Interface

The cable definition of the DSOD705 sensor is as follows:

Wire ColorFunction
Red wirePower +, +24 VDC
Black wirePower -, GND
Yellow-green wireRS-485 A / 485_A
White wireRS-485 B / 485_B
Blue wireRelay +
Green wireRelay -
Brown wire4-20 mA +
Gray wire4-20 mA -
Bare wireShield

In this solution, the following interfaces are mainly used:

DSOD705KC11 / External Power Supply
Red wire +24 VPositive terminal of external 24 VDC power supply
Black wire GNDNegative terminal of external 24 VDC power supply
Yellow-green wire 485_AKC11 RS-485 A
White wire 485_BKC11 RS-485 B
ShieldRecommended to be grounded or handled according to on-site EMC requirements

Sensor Interface

This solution uses the RS-485 / Modbus RTU interface of the DSOD705 for data acquisition.

The 4-20 mA and relay interfaces are not used as the main data acquisition path in this solution. They can be independently connected to a local control or alarm system according to on-site requirements.


5. Data Acquisition

In this solution, the following register is read through Modbus:

Acquisition ContentFunction CodeStart AddressRegister QuantityData TypeDescription
Sensor value0x040x00002Float, DCBA / Little EndianReads the water surface oil spill detection value

KC11 periodically reads the DSOD705 input registers 0x0000 ~ 0x0001 through EdgeBus logic. The read result is parsed as FloatLE and reported to ThinkLink as the oil field.


5.1 Register Definition

Read-only Registers

Register AddressLengthR/WData TypeDescription
0x00002RFloat(DCBA)Read sensor value
0x00012RFloat(DCBA)Read sensor temperature
0x00106RASCII-HEXRead sensor SN value
0x00162RHEXRead sensor hardware and software version

Note: In the integration code, the actual read range is 0x0000 ~ 0x0001, meaning two registers are read to form one floating-point value for obtaining the oil contamination detection value.

Holding Registers

Register AddressLengthR/WData TypeDescription
0x00001R/WShortRead / set current sensor address, range 1-247
0x00011R/WShortBaud rate: 0=4800, 1=9600, 2=19200, 3=56000, 4=57600, 5=115200
0x00021R/WShortDetection interval time, unit: ms
0x00062R/WFloat(DCBA)Distance from sensor to water surface, unit: m
0x00101R/WShortRelay control switch, 0=Off, 1=On
0x00122R/WFloat(DCBA)Relay control maximum value
0x00142R/WFloat(DCBA)Relay control minimum value
0x00162R/WFloat(DCBA)Relay action delay time, unit: ms
0x00201R/WShort4-20 mA output mode
0x00222R/WFloat(DCBA)Sensor value corresponding to 4 mA current
0x00242R/WFloat(DCBA)Sensor value corresponding to 20 mA current
0x00261R/WShort4 mA current calibration value, range 7900-9900
0x00271R/WShort20 mA current calibration value, range 1700-3700
0x00302R/WFloat(DCBA)Sensor K value
0x00322R/WFloat(DCBA)Sensor B value

5.2 Status Bit Definition

In this solution, EdgeBus / PayloadParser generates a status field named status. The current script uses the following status judgment:

Status BitJudgment MethodMeaning
bit1(status & 0x02) === 0x02Modbus acquisition timeout

When a timeout status is detected, the thing model script retains the previous telemetry data frame of the device and only updates the status field. This prevents platform-side business data from being cleared due to the current acquisition timeout.


6. EdgeBus Model

The DSOD705 itself is an RS-485 / Modbus RTU sensor, not a native LoRaWAN device. Therefore, KC11’s built-in EdgeBus logic is required to complete Modbus acquisition and LoRaWAN reporting.


6.1 EB Configuration Parameters

ParameterValue
EB namedsod705
LoRaWAN Port22
Version0x86
DataType0x07
Business code BzType22107
Business version BzVersion11
Serial baud rate9600
Data bits8
Stop bits1
ParityNONE
Modbus function code0x04
Modbus addressStored at APP parameter address 150
Upload period parameterAPP parameter address 70
Acquisition period parameterAPP parameter address 74
COV parameterAPP parameter address 110
Acquisition register0x0000 ~ 0x0001
COV typeFloatLE

Parameter description:

  • The upload period and acquisition period are configured separately.
  • The upload period is stored at APP parameter address 70.
  • The acquisition period is stored at APP parameter address 74.
  • The acquisition period must be shorter than the upload period.
  • The COV parameter is stored at APP parameter address 110.
  • The Modbus address is stored at APP parameter address 150.

6.2 EB Code

typescript
import {Buffer} from "buffer";
import {buildOtaFile} from "@EBSDK/run";
import {LoraUpEvent} from "@EBSDK/EBCompiler/all_variable";
import {EBModel} from "@EBSDK/EBCompiler/EBModel/EBModel";
import {EventInfoItem} from "@EBSDK/EBCompiler/plugins/EBHelper";
import type {UserConfUPItem} from "@EBSDK/EBCompiler/plugins/EBHelper";
import {CheckbitEnum, getOtaConfig, HwTypeEnum, UpgrdTypeEnum} 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}, //covAppIndex:
                ]
            }
        ]
    }
]
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)
}
buildOtaFile(import.meta.url, otaConfig, MODBUS_TT)

6.3 Description

The current EB logic is described as follows:

  1. KC11 communicates with the DSOD705 through the RS-485 interface.
  2. The serial port parameters are 9600, 8N1, meaning 9600 bps, 8 data bits, 1 stop bit, and no parity.
  3. The EB logic uses Modbus function code 0x04 to read input registers.
  4. The read address range is 0x0000 ~ 0x0001, with a total of 2 registers used to parse one FloatLE value.
  5. The acquisition result is reported through LoRaWAN Port 22 as the oil spill detection value.
  6. The upload period is controlled by APP parameter address 70.
  7. The acquisition period is controlled by APP parameter address 74.
  8. The COV change threshold is controlled by APP parameter address 110.
  9. The Modbus slave address is controlled by APP parameter address 150.
  10. The business code is 22107, and the business version is 11.

7. Thing Model

7.1 Basic Thing Model Information

Data Thing Model

ItemDescription
NameDSOD705
id Namedsod_22107
LoRaWAN Port22
Data length16
RSSISupported
Battery fieldindex 4
Business identifier Tag0x86
Data type Tag0x07

Parameter Thing Model

ItemDescription
NameDSOD705-PARA
id Namedsod705_para_22107
Parameter reporting Port214
RPC namedsod705_set_para_22107

Byte PositionContent
index 0Tag: 0x86
index 1Tag: 0x07
index 4Battery
index 6oil, FloatLE
OthersEdgeBus status, RSSI, and other auxiliary fields

Data Field Definition

Field Namefield_nameUnitIndexTypeCoefficientDecimal Places
oiloil%6floatLE12

Parameter Field Definition

APP Parameter AddressField Namefield_nameUnitTypeDescription
70period_upperiod_upSuint32leUpload period
74period_readperiod_readSuint32leAcquisition period
110cov_oilcov_oil%floatLECOV threshold of oil spill detection value
150addr_modbusaddr_modbusuint8Modbus slave address

7.3 Thing Model Script

Data Thing Model Script

javascript
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
}

Parameter Thing Model Script

javascript
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. Third-party Platform Data Subscription

8.1 MQTT Topic

latex
/v32/{Organization Account}/tkl/up/telemetry/{eui}

8.2 Example Reported Data

json
{
    "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
    }
}

Field Description

FieldMeaning
euiLoRaWAN terminal EUI
active_timeData reporting time
thingModelIdThing model ID
thingModelIdNameThing model name
snrLoRaWAN signal-to-noise ratio
rssiLoRaWAN signal strength
batteryDevice battery / power status field
oilDSOD705 oil spill detection value, unit: %
statusEdgeBus / Modbus acquisition status

9. RPC

9.1 RPC Name

This solution includes two RPCs:

RPC FunctionNameid Name
Set parametersDSOD705 SET paradsod705_set_22107
Read parametersDSOD705 GET paradsod705_get_22107

The internal RPC name used for parameter setting is:

latex
dsod705_set_para_22107

9.2 Parameter Definition

Parameterfield_nameAPP AddressUnitTypeDescription
period_upperiod_up70Suint32leUpload period
period_readperiod_read74Suint32leAcquisition period
cov_oilcov_oil110%floatLECOV threshold of oil contamination detection value
addr_modbusaddr_modbus150uint8Modbus slave address

Parameter setting recommendations:

  • period_read should be smaller than period_up.
  • addr_modbus should be consistent with the actual Modbus address of the DSOD705 sensor.
  • cov_oil is used to control the change reporting threshold of the oil contamination detection value and can be configured according to on-site sensitivity requirements for oil contamination detection.

9.3 RPC Code

Parameter Setting RPC

javascript
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

Parameter Reading RPC

javascript
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. Template Selection

In the ThinkLink platform, search for the template:

latex
DSOD705

Or search for the thing model id Name:

latex
dsod_22107

For the parameter thing model, search:

latex
dsod705_para_22107

For RPC, search:

latex
dsod705_set_22107
dsod705_get_22107

Alternatively, search by business type:

latex
Water surface oil spill detection
Non-contact oil spill detection
RS-485 oil spill sensor
Modbus RTU water quality / environmental monitoring
LoRaWAN industrial sensor access