Milesight EM300-CL: LoRaWAN Capacitive Liquid Level Sensor

Milesight EM300-CL LoRaWAN capacitive level sensor: own ChirpStack/ThingsBoard decoder, decoded example and liquid status alarms.

Milesight EM300-CL
EM300-CLSensor
LoRaWAN
Class A, OTAA
Band / port
EU868 / port 85
Detection
Capacitive, non-contact (dual electrode)
Ingress protection
IP67
Container fit
Adapts to various tank shapes and sizes
Battery
Replaceable, up to 10 years
Configuration
NFC (Milesight ToolBox)
Measurements

What the EM300-CL measures

Liquid status

Capacitive point detection: full, critical low level, uncalibrated or error.

Critical level alarm

Immediate uplink when the liquid drops below the calibrated threshold, with alarm and release events.

Calibration result

Reports whether the latest container calibration succeeded or failed.

Battery level

Reported periodically as a percentage, with local storage and retransmission.

Data into your dashboard

Integration

Sensor / controller

Measures or controls in the field and sends LoRaWAN uplinks.

LoRaWAN gateway

Receives the radio packets and forwards them to the server.

ChirpStack

Network server: manages sessions and decodes the payload.

ThingsBoard / Grafana

Dashboards, alarms, rules and reports.

ChirpStack v4 · decodeUplink
function decodeUplink(input) {
  var bytes = input.bytes;
  var data = {};

  var LIQUID = { 0: "uncalibrated", 1: "full", 2: "critical low level", 255: "error" };
  var ALARM = { 0: "alarm release", 1: "critical low level alarm" };
  var CAL = { 0: "failed", 1: "success" };

  for (var i = 0; i < bytes.length; ) {
    var channel = bytes[i++];
    var type = bytes[i++];

    if (channel === 0x01 && type === 0x75) {          // battery (%)
      data.battery = bytes[i]; i += 1;
    } else if (channel === 0x03 && type === 0xed) {   // liquid status
      data.liquid = LIQUID[bytes[i]] || "unknown"; i += 1;
    } else if (channel === 0x04 && type === 0xee) {   // calibration result
      data.calibration_result = CAL[bytes[i]] || "unknown"; i += 1;
    } else if (channel === 0x83 && type === 0xed) {   // liquid alarm
      data.liquid = LIQUID[bytes[i]] || "unknown";
      data.liquid_alarm = ALARM[bytes[i + 1]] || "unknown"; i += 2;
    } else if (channel === 0xff) {                    // device info (join/power-on)
      break;
    } else {
      break;
    }
  }
  return { data: data };
}

Implemented from the published Milesight byte specification (Communication Protocol / User Guide).

Channel format: 01 75 battery (%), 03 ed liquid status (0 uncalibrated, 1 full, 2 critical low level, 255 error), 04 ee calibration result (0 failed, 1 success), 83 ed critical-level alarm (status byte plus alarm type). Device-info channels (0xFF, e.g. protocol/firmware/serial on join) are skipped by the loop. This is implemented from the published Milesight byte specification. For ThingsBoard the same channel logic goes into an uplink converter.

Uplink (hex)

01756403ED01

Decoded JSON

{ "battery": 100, "liquid": "full" }
Where it fits

Use cases

Smart restroom refills

Track soap and hand wash levels so cleaning crews refill only when needed.

More

Consumables monitoring

Detect empty or near-empty dispensers and containers across a building.

Facility operations

Route critical low-level alarms into the dashboard for predictable restocking.

From the field

Configuration & pitfalls

Calibration is mandatory

Capacitive detection only works after a container calibration. Until then the sensor reports uncalibrated, so calibrate against the empty and full container before going live.

NFC setup

Keys, reporting interval and alarm thresholds are set over NFC with the Milesight ToolBox before rollout.

Critical-level alarms

Sent immediately, outside the reporting interval. Dashboard rules should treat 83 ed alarm uplinks as priority events.

Container fit

The dual-electrode probe adapts to different tank shapes but liquid type (soap, water, oil) changes capacitance. Recalibrate when you switch the medium or container.

Your partner

How merkaio supports your EM300-CL

From sourcing to day-to-day operation, all from one partner on our own European infrastructure.

Pre-staging & provisioning

We configure the EM300-CL, set keys, intervals and alarms, and ship it ready to deploy.

Own decoder

Payload codec for ChirpStack v4 and ThingsBoard, implemented from the Milesight specification.

Dashboard integration

Data lands in your ThingsBoard or Grafana, with alarms and reports.

Operations & monitoring

We run the LoRaWAN stack and dashboards on European infrastructure, you just use the data.

Frequently asked questions

Yes. It is a standard LoRaWAN device, no Milesight gateway or cloud required. You add the codec to the device profile and provision it via OTAA.
Yes, for both ChirpStack and ThingsBoard, implemented from the published Milesight byte specification. The same channel logic goes into a ThingsBoard uplink converter.
It is a capacitive point-level sensor: it reports whether the liquid is above or below the calibrated detection point as a status (full, critical low level), not a continuous depth in centimetres. The dual electrodes detect the medium without direct contact through the container wall.
It is a Class A device on LoRaWAN port 85. Each uplink carries the liquid status; the battery level is reported periodically as a percentage.
Capacitive detection has to be calibrated to the specific container and medium first. Before that calibration the device reports an uncalibrated status, so run the calibration over NFC before relying on the readings.
It ships with a replaceable battery rated for up to ten years, depending on the reporting interval and how often critical-level alarms fire.
Yes. When the liquid drops below the calibrated point the device sends an immediate 83 ed alarm uplink, and a separate release event when the level recovers, so dashboard rules should treat both as priority events.
From the same series

Related devices

Let's discuss your infrastructure. Digital and on-site.

Whether it's IoT platform development, hardware selection, managed hosting for ChirpStack, ThingsBoard, Grafana or NetBird VPN, or migration from a self-hosted setup - we'll find the right solution for your use case. Book a free 30-minute consultation, no commitment required.

Timo Wevelsiep

Your contact

Timo Wevelsiep

Founder, merkaio

15 minutes, no commitment, directly with Timo.

By submitting, you agree to our Privacy Policy.

Decoder for ChirpStack v4. merkaio is an independent integrator and is not affiliated with Milesight.