Field notes · battery-powered BLE irrigation controllers

Your irrigation timer already talks. It just doesn't talk Wi-Fi.

This is about Galcon battery irrigation timers — the 6100 family and its relatives, sold as DC-6100, GL6100 and similar, the ones that pair over Bluetooth with the manufacturer's phone app and talk to nothing else. A small always-on computer puts them on Wi-Fi, into Home Assistant, and under real automation. Here is the working software, the protocol detail you'll need, and the parts.

Galcon DC-6100 / 6100 series Home Assistant / MQTT Battery decoding published here first
A watered garden on the left, a solar array being rinsed on the right, joined by a light arc
One controller, two jobs: the garden and the panels.
An irrigation tap timer with a wireless data arc
The timerSpeaks Bluetooth and nothing else, until you give it a bridge.
Young trees with drip emitters catching the light
The gardenWatering that answers to rain and soil, not to a calendar.
Water sheeting off a solar panel
The panelsA scheduled rinse that skips itself when it has rained.

Is this your controller?

Everything here was worked out against a Galcon DC-6100 and verified against a live unit. If yours matches the description below, this page is for you.

Closely related models in the same family behave the same way on the wire. A controller from a different maker, or a mains-powered one, is a different animal and none of the byte offsets below will apply to it. Nothing here is affiliated with or endorsed by any manufacturer.

Start with the software

You do not need to write any of this yourself. There is a maintained open-source project that already does the hard part: it connects to the controller, reads live status, edits schedules, and publishes everything to MQTT with Home Assistant auto-discovery.

Open source · Python

py-galcon-bt-control

Desktop GUI with live status and schedule editing, command-line tools, and an MQTT bridge with Home Assistant auto-discovery. Windows installer for x64 and ARM64; runs fine headless on a Raspberry Pi. Not affiliated with the manufacturer.

What it runs on. This is Python, so it needs a small always-on computer — a Raspberry Pi, a mini PC, a NAS, anything running Linux — placed within Bluetooth range of the controller. It does not run on a bare ESP32 board. That distinction decides what you need to buy, so it is worth getting right before you order anything.

Get it on GitHub →

Install that first and confirm you can see your controller. Everything below assumes it is running and talking.

What this page adds

The project above documents the service, the characteristics, the active-zone byte and the open/close commands. Those are settled and this page does not restate them as new. What follows is the part that was still open — most of the status frame, and the battery.

FieldWhereStatus
Service & characteristics—already documented
Active zones, remaining timestatus[0], [2–3]already documented
Valve open / closecmd[0], [1]already documented
Battery level and low thresholdstatus[10–11]new here
Input voltage, power ratingstatus[1]new here
Sensor wet, master, fertilizer, ACstatus[9]new here
Rain-off days remainingstatus[12]new here
Valve count, DC/AC typestatus[13]new here
Firmware, signal, water budgetstatus[14–16]new here
Duration as h / m / scmd[3–5]refined
Rain-off and water-budget commandscmd[2], [6], [7]new here

The battery reading

This is the field everyone gets wrong, and there is a good reason for it. Byte 10 on its own looks like nonsense — it climbs and wraps and never behaves like a percentage. It is not a percentage. It is the low half of a 16-bit value.

batteryLevel = status[11] << 8 | status[10]     # little-endian, raw ADC counts

lowBattery   = batteryLevel <= 3123    when input is  9 V
             = batteryLevel <= 2947    when input is 18 V

The number is a raw converter count, not millivolts and not a percentage. Do not render it as volts — a fabricated unit is worse than an honest raw figure. What makes it useful is that the thresholds above are the same ones the controller's own app uses to decide when to warn you, so an integration can raise "battery low" at exactly the right moment instead of at a guessed number.

Once you can read the level9V alkaline, multipackWith a real battery reading you can stock replacements before a zone silently stops watering.

Which threshold applies

Bit 6 of status[1] tells you the controller's input voltage: set means 18 V, clear means 9 V. Read it per frame rather than assuming — the same protocol covers both.

inputVolts = (status[1] >> 6) & 1 ? 18 : 9

A worked example. A resting frame of ff 00 … 08 a6 0e 00 db 2f b1 64 gives byte 10 = 0xa6 (166) and byte 11 = 0x0e (14), so the level is 14×256 + 166 = 3750. Byte 1 is zero, so the input is 9 V and the threshold is 3123. The pack is healthy.

The rest of the status frame

Twenty bytes, read from the status characteristic. Offsets not listed here are either already covered by the project above or have no established meaning.

ByteMeaningHow to read it
1Input voltage, power ratingbit6 → 18 V / 9 V  ·  bit7 → rating
9Device flagsbit0 sensor wet · bit1 master open · bit2 fertilizer · bit3 AC present
10–11Battery levelLE16, raw counts
12Rain-off days remaining0 = not in rain-off
13Valve count and supply typebits0–2 → lookup below  ·  bit3 set = DC
14Firmware versioninteger
15Signal strengthunsigned — subtract 256 for dBm
16Water budgetpercent

Valve count lookup

Bits 0–2 of byte 13, read least-significant first and concatenated, index a table rather than encoding the count directly:

{ 000: 0,  100: 1,  010: 2,  110: 4,
  001: 6,  101: 9,  011: 12, 111: 12 }

So a controller reporting 110 has four valves. Worth checking against what your own bridge enumerates — if the two disagree, trust the bridge and tell me.

Commands beyond open and close

The command frame is twenty bytes, all zero except the fields you set. Byte 2 acts as an opcode for the device-wide settings; the valve commands leave it at zero.

ByteFieldEncoding
0Close valvezone number
1Open valve0x80 | zone number
2Opcode1 = rain-off   2 = water budget
3–5Durationhours, minutes, seconds
6Rain-off days0 clears it
7Water budgetpercent

Duration is a full h/m/s triple, not a single minutes byte. That matters for the short cycles these controllers are good at — ten-second bursts for propagation misting, or the sub-minute pulses a panel rinse wants.

Give the capacitor time

Battery models drive a latching solenoid from a capacitor, and the capacitor needs to charge before it can throw the valve. The app waits a full six seconds after connecting before it sends any valve command. If your writes are accepted but the valve never moves, this is almost always why — shorter empirical waits work most of the time, which is exactly what makes the failure so confusing.

The bridge boardESP32-C3 SuperMiniWi-Fi and BLE on one chip. Sits within radio reach of the controller and relays to your network.

What you actually need to buy

The controller only speaks Bluetooth LE, and BLE range is short. So you need one thing within radio reach of it that also holds a Wi-Fi link back to your network. What that thing is depends on which software you run, and the two answers are genuinely different.

Route A · recommended

A small Linux computer

Runs py-galcon-bt-control or ble2mqtt — both are Python. You get the full picture: live status, the battery reading below, and schedule editing. A Raspberry Pi Zero 2 W is enough, and any Pi, mini PC or NAS you already own will do, provided it sits close enough to the controller and stays on.

Route B · firmware only

An ESP32 board

Cheaper and needs no computer, but be honest about the state of it: the one published ESPHome component for this hardware targets a different model in the family and has not been touched since 2023. Treat it as a starting point to adapt, not as something that will work the day it arrives.

If you just want it working, take route A. The boards below are listed for route B and for anyone who likes flashing firmware — not as a substitute for the computer route A needs.

Affiliate disclosure. The product links below are affiliate links. If you buy through them the price is unchanged for you and this page earns a small commission. Prices were correct when the page was built and will drift.

Route A — the computer and its two consumables

A word on the board itself: buy it from an official Raspberry Pi reseller, not here. Marketplace listings for genuine Pi boards run well above retail and sell in ones and twos, so there is no link for it below — and if you already own any always-on Linux machine near the controller, you need neither the board nor these two items.

StorageSanDisk Ultra A1 microSDThe card the Pi boots from. A1 rating matters more than capacity here — 32 GB is plenty, and a cheap unbranded card is the most common cause of a Pi that corrupts itself after a few months.from $15.60View on AliExpress
Power5V 3A micro-USB supply, with switchMicro-USB, which is what a Zero takes — not the USB-C a Pi 5 wants. The inline switch is worth having on a headless machine you will occasionally need to power-cycle.$5.68View on AliExpress

ESP32 boards (route B)

Bridge boardESP32-C3 SuperMiniWi-Fi and BLE on one chip, thumbnail-sized, runs on USB power. The cheapest thing that does the whole job.$3.73View on AliExpress
AlternativeESP32-S3 / C3 ZeroMore memory and IO if you want the bridge to drive anything else — a relay, a flow meter, a moisture probe.$4.38View on AliExpress
Packaged optionM5Stack ATOM LiteThe same ESP32 already in a case, with USB-C and a button. Costs a little more than a bare board and saves you finding an enclosure for something that lives outdoors.$6.40View on AliExpress
EnclosureIP67 clear project boxThe bridge lives outdoors near the valves. A clear lid lets the status LED through without opening it.$4.80View on AliExpress
EnclosureIP67 box with haspLarger, hinged, easier to open in the field if you expect to touch the hardware more than once.$8.51View on AliExpress

For the controller

Power9V alkaline, multipackNow that you can read the real battery level, you can stock replacements before a zone silently stops watering.$7.06View on AliExpress
Power9V 1100mAh alkalineHigher capacity cells for controllers driving several valves through a full season.$11.52View on AliExpress
ValveDC latching solenoidThe valve type these controllers drive. Useful as a spare, or to add a zone the controller already supports.$18.20View on AliExpress

Application: washing solar panels on a schedule

Solar array with a sprinkler manifold misting the panel glass at sunrise
A row of nozzles along the array turns an expensive call-out into a schedule.

This is the use that justified the whole exercise, and it is not what these controllers are sold for.

Rooftop panels lose output to dust. The usual answer is to book a cleaner a few times a year, which is expensive and badly timed — you pay whether the panels needed it or not. A few irrigation valves plumbed to sprayers along the array turn that into a scheduled rinse, and once the controller is on Wi-Fi the schedule can respond to conditions instead of a calendar.

Two things make this work properly, and both need the controller to be readable rather than just writable:

Short cycles matter here, which is why the h/m/s duration encoding above is worth having — a panel rinse is a couple of minutes per zone, staggered, not a garden soak.

Manual backupWater-fed pole brush kit, 12–15ftFor the twice-a-year deep clean the sprayers won't do, and for reaching panels the fixed nozzles miss.$45.95View on AliExpress

Use mains or filtered water if you can. Hard water dries to a mineral film that costs you more output than the dust did.

Application: the garden it was built for

The ordinary use, done properly once the controller is no longer a black box.

Out of the box these timers run a fixed weekly schedule that you edit by crouching in front of the unit with your phone. On Wi-Fi, the same hardware becomes something you can drive from conditions: skip a cycle after rain, shorten everything in a cool week with the water-budget command, extend it in a heatwave, and get a notification when a battery is genuinely low rather than when a zone has already failed silently.

The water budget is the underused one. It scales every programmed duration by a percentage in a single write — opcode 2 with a percent in byte 7 — so seasonal adjustment does not mean rewriting every schedule record.

DistributionDIY drip irrigation kit, 10–30mDrippers, tubing and connectors to get from the valve to the plants. The controller handles timing; this handles delivery.$10.34View on AliExpress
DistributionMicro drip system, 20m adjustableAdjustable emitters for pots and balconies, where per-plant flow varies more than in a bed.$7.16View on AliExpress

What else opens up

Once status is readable and commands are writable from your own code, the controller stops being an appliance and becomes a component.

Other Bluetooth irrigation controllers

This page is about one family. Several other BLE timers have community work behind them, at varying depth. Rather than restate any of it, here is where to look.

ControllerWhere the work is
Galcon 9001BT / 11000suborb/GalconController — Python, documents a shorter 7-byte frame format used by that generation
Galcon 9001BT on ESP32sr01/gl9001-esphome — an ESPHome component, the closest thing to a drop-in Wi-Fi bridge
Generic BLE deviceszewelor/bt-mqtt-gateway and devbis/ble2mqtt — extensible BLE-to-MQTT gateways worth starting from for an unsupported timer

The two Galcon generations are not compatible: the newer one uses 20-byte frames and a different service, the older one 7-byte frames. Code written for one will connect to the other and then quietly do nothing useful.

Also on this site