[RELEASE] Rain Bird LNK/LNK2 WiFi Module Controller

:zap: [RELEASE] Rain Bird LNK/LNK2 WiFi Module Controller v0.1.0.0

Author: @MHedish
Category: Device Drivers → Utility / Irrigation

Version Status License

Advanced Hubitat driver providing full local LAN control of Rain Bird LNK/LNK2 WiFi irrigation controllers — including zone, program, and rain delay management. Features automatic time sync, telemetry, adaptive refresh, and support for ESP-TM2 and ESP-Me controllers.

:rocket: Overview

My next abandonware release. :wink:

This time, the original author, @craigde, even shared earlier this year that he abandoned his beta driver a few years ago. :grin:

I was never able to get that five-year-old code to work, but it did plant the seed for this, and it had a helpful opcode reference for older firmware. Thanks, @craigde! :clap:

You should know, this driver is helpful for more than just monitoring your controller; you can use it to integrate any motion detectors and/or event-driven security cameras to automatically deal with folks like this:

This driver not only allows for integrated Hubitat monitoring and control, it addresses a major Rain Bird oversight: time synchronization. The internal real-time clock (RTC) is notorious for drift, yet Rain Bird has no way to automatically update the RTC or for addressing Daylight Saving Time adjustments.

Their solution is either directly through the front panel or manually through the mobile app, despite being Wi-Fi connected (NTP). Not anymore; this driver recognizes DST and automatically sets the controller for you. The RTC is kept within +/- 5 seconds (typically <2) of the Hubitat clock.

All events and telemetry are fully Rule Machine and WebCoRE compatible, enabling precise automation and monitoring with minimal resource overhead.

It communicates directly with your Rain Bird controller over LAN — no cloud, no accounts, no internet dependency.

There are many versions of controller firmware out there, and none of them are field upgradable, so YMMV when it comes to capabilities, but this version of the driver does everything I need it to. :muscle:

See the Changelog for full release notes.

:star2: What’s in v0.1.0.0 (Release Candidate)

:jigsaw: Hybrid + Modern Firmware Convergence — validated on firmware 2.9 and 3.2
:droplet: Switch & Valve capabilities: dashboard integration for on/off/open/close parity
:clock3: Time sync reliability: hourly drift checks, DST detection, and random offset scheduling to reduce hub load
:repeat: Deterministic refresh engine: resilient pacing and adaptive polling under watering conditions
:chart_with_upwards_trend: Diagnostics: testAllSupportedCommands() now emits firmware and module identity

:gear: Installation

Option 1: Hubitat Package Manager (Recommended)

  1. Open Hubitat Package Manager (HPM) from your Hubitat Apps list.
  2. Choose Install → Search by Keyword.
  3. Enter Rain Bird or Irrigation in the search box.
  4. Select Rain Bird LNK/LNK2 WiFi Module Controller from the results and install.
  5. Once installed, open the new device’s Preferences, and enter the Rain Bird Controller IP address and Rain Bird Controller Password. Click Save Preferences.

Option 2: Manual Installation

  1. In Hubitat, go to Drivers Code → + New Driver.
  2. Click Import, then paste this URL:
https://raw.githubusercontent.com/MHedish/Hubitat/refs/heads/main/Drivers/RainBird-LNK/RainBird-LNK-Wi-Fi-Module.groovy
  1. Click Import, then Save.
  2. Go to Devices → Add Device → Virtual, then:
  • Name your device (e.g., Sprinkler).
  • Under Type, select Rain Bird LNK/LNK2 WiFi Module Controller.
  • Click Save Device.
  1. Enter your Rain Bird Controller IP address and Rain Bird Controller Password under Preferences, then click Save Preferences.

:three: Verification

  • A Configure command will automatically run once you save preferences and will populate that attribute panel.-
  • Confirm the firmwareVersion and zoneCount attributes populate.
  • Run a short Run Zone (1, 2 min) test to verify control.

:four: Optional: Diagnostics

  • Execute testAllSupportedCommands() to validate controller capabilities.
  • Review output in Logs or driverStatus.

:globe_with_meridians: Key Features

  • :lock: 100% local control — no cloud API required
  • :gear: Adaptive opcode negotiation for LNK and LNK2 controllers
  • :clock3: Auto Time Sync keeps controller time accurate
  • :droplet: Per-zone and per-program control with dynamic detection
  • :umbrella: Rain delay and rain sensor status integration
  • :bar_chart: Telemetry-rich diagnostics and event logging
  • :stopwatch: Cron compatibility fallback — supports both pre- and post-2.3.9.x Hubitat CRON parsers
  • :brick: Designed for Hubitat C-7 / C-8 / C-8 Pro (AES-128 LAN encryption)

:jigsaw: Compatibility

Controller WiFi Module Firmware Status Notes
ESP-TM2 LNK / LNK2 2.1 – 3.0 :white_check_mark: Stable Tested on 2.1 and 2.9
ESP-Me LNK / LNK2 2.9 – 3.2 :white_check_mark: Stable Multi-zone hybrid support
ESP-Me3 LNK2 4.0+ :warning: Partial Extended telemetry not yet implemented
ST8 / ST8i LNK 2.5 – 3.0 :warning: Limited Basic zone control only

:brain: Hubitat Platform

Platform Version Status
C-7 / C-8 / C-8 Pro 2.3.9+ :white_check_mark: Fully supported
C-5 2.3.6+ :warning: Works (slightly slower crypto)
C-4 :x: Not supported

:droplet: Common Commands

Command Description
Advance Zone Jump to the next zone (firmware-aware)
Off/Close Same as Stop Irrigation
On/Open Same as Run Program 'A'
Refresh Force telemetry update
Run Program (A–D) Start controller programs
Run Zone Start a zone for a specified duration
Set Rain Delay Apply a rain delay (0–14 days)
Stop Irrigation Halt all watering activity

:bar_chart: Exposed Attributes

Attribute Type Values / Notes
activeZone number Currently active zone number
autoTimeSync boolean Whether auto time synchronization is enabled
availableStations string List of active zones/stations detected
clockDrift number Time drift between hub and controller (seconds)
controllerDate string Controller-reported date
controllerTime string Controller-reported time
delaySetting number Rain delay duration (days)
driverInfo string Driver metadata including version and mode
driverStatus string Current driver health or command response
firmwareVersion string Controller firmware revision
irrigationState string watering, idle, or off
lastEventTime string Timestamp of last received event
lastSync string Timestamp of last successful time sync
model string Controller model identifier
programScheduleSupport boolean Indicates if controller supports program retrieval
rainDelay number Current active rain delay days
rainSensorState enum bypassed, dry, wet
remainingRuntime number Seconds left in current watering cycle
seasonalAdjust number Active seasonal adjustment factor (%)
serialNumber string Controller serial number
switch enum on, off
valve enum open, closed
waterBudget number Seasonal watering percentage
watering boolean Indicates irrigation is currently active
wateringRefresh boolean Internal refresh flag during watering
zoneAdjustments string JSON string of per-zone runtime adjustments
zoneCount number Number of detected zones

:test_tube: Diagnostics

Command: testAllSupportedCommands

Tests controller for all supported opcodes and emits results to driverStatus and log.
Also reports firmware and module diagnostics (LNK / LNK2).


:warning: Troubleshooting & Common Issues

Symptom Possible Cause Recommended Action
503 Service Unavailable Controller is processing or rate-limited Allow 2–3 seconds between commands; driver auto-retries with adaptive pacing
Clock drift Controller RTC inaccuracy Enable Auto Time Sync (default) to maintain accuracy
Controller unresponsive DHCP renewal or IP conflict Reserve static IP for the controller in router's DHCP settings
Zone list empty First refresh incomplete or older firmware Click Refresh, wait 10 seconds, then recheck zoneCount
Rain delay stuck Controller cache sync Run Refresh or Stop Irrigation, then retry command
Sluggish updates Poll interval too long Lower Refresh Interval to 2 minutes during active watering season
Repeated log noise Debug mode active Debug logging turns off automatically after 30 minutes

:bulb: Tip: For the most reliable operation, use a reserved DHCP IP and enable automatic time sync.

:compass: Best Practices

:clock3: Time Synchronization

Rain Bird controllers lack NTP or any remote clock-set capability, causing significant drift over time. The driver’s Auto Time Sync function compensates for this limitation by:

  • Automatically comparing controller time to Hubitat every hour.
  • Correcting any drift greater than ±5 seconds.
  • Adjusting for DST changes and randomizing sync intervals to prevent network bursts.

:white_check_mark: Recommended: Keep Auto Time Sync enabled at all times. This ensures that program start times and watering schedules remain accurate — even after power loss and DST adjustments.

:sun_behind_small_cloud: Refresh Interval Tuning

The refresh interval defines how often Hubitat polls the controller for status updates.

  • Active Season: 2-minute refresh (recommended for zone monitoring and dashboards)

  • Normal Operation: 5–15 minutes to balance performance and network traffic

  • Winterized / Off-Season: 60–480 minutes or manual refresh mode
    When set to manual, the Automatically sync Rain Bird to Hubitat clock preference will still keep the clock synchronized once an hour while not polling the controller for other status information.

  • If you choose the Increase polling frequency during watering events option (default), the polling will go up to once every 5 seconds during a watering event to give you almost real-time information. When the watering is over, the polling will go back to the frequency you had set before.

    :white_check_mark: Use shorter intervals during watering periods for near real-time zone feedback.

  • It's still best to allow the Rain Bird controller to manage automatic watering, but if you want to manage it within Hubitat, you can now use Hubitat’s Rule Machine or WebCoRE to automate watering windows, including the water budget attribute to reduce watering based on the forecasted weather.

  • Avoid scheduling overlapping zones to minimize command queue congestion.

  • When creating custom schedules, leave 3–5 seconds between zone transitions for pacing stability.

  • You can create a routine to update refreshInterval to one minute just before your scheduled watering event and then monitor/record the program status via Hubitat. Set an event for watering==false and then reset the refreshInterval to either 15 minutes or manual.

:video_camera: Security Camera

If you are going to use this to deal with porch pirates, stray animals, or people that can't read no parking signs like the examples earlier, be sure to capture it on video for the rest of us to enjoy. :boom: :laughing:

🖧 Network Stability

  • Reserve a static IP for your Rain Bird controller in your router.
  • Ensure the Wi-Fi signal to the LNK/LNK2 module is at least −65 dBm or better.
  • Avoid placing the module near metal enclosures or irrigation boxes with poor reception.

:herb: Following these best practices ensures precise irrigation scheduling, minimal drift, and consistent LAN reliability — even on controllers without native NTP or cloud sync capabilities.


:speech_balloon: Feedback

This driver has been validated against firmware 2.9 and 3.2. Any other platform additions are welcome.

Please report feedback or findings in this thread to help continue improving the integration, and I can promote this from RC to Production. :champagne:


:link: GitHub Repository:
:point_right: Rain Bird LNK/LNK2 WiFi Module Controller (Hubitat Driver)

:scroll: License: Apache License, Version 2.0
:technologist: Author: @MHedish
:handshake: Acknowledgments: Thanks to the Hubitat community developers whose earlier work made this driver possible, including @cragide and @allen.porter.


🩵 Support & Credits

Developed and maintained by Marc Hedish
Documentation by ChatGPT (OpenAI)
License: Apache 2.0

:coffee: Support development: paypal.me/MHedish

3 Likes

I've been hoping that somone would try to reserect or create a new app. I am going to install it and give it a try.

1 Like

Got a little time today and was able to install and do a little testing. I Executed testAllSupportedCommands and got the following

The warn looks like there is a typo "uri" instead of "url"?

Controller State is showing "Watering" before and after running a zone (tested 1 zone for 1 minute).

That's 1) Hubitat's text, not mine; 2) It's not a "typo" URI (Uniform Resource Identifier) is the broader category for resource identification, a URL (Uniform Resource Locator) is a specfic type within that broader category. :wink:

Back to the diags... the command support looks good as does the firmware (3.2). The really odd stuff there is the date/time attributes.

Which model controller is this? I tested against an ESP-me

1 Like

I learned something today. Thanks.

Mine is an ESP-TM2

I power cycled it and now it is showing "controllerTime=13:34:25 (13:34:25)", I guess I made it return from the future :rofl:

Progress! The TM2 is a "simpler" controller but looking at the diag you pasted it appears to have all of the opcodes we neeed.

Go ahead and turn on both Enable Debug Logging and Log All Events in preferences. When you click on Save and Close the driver will automatically run a configure() event. That will give us all sorts of info to look at in the debug log.

You should be able run a zone and use stop to cancel everything.

I'm curious to solve the getAvailableStations() error there. Here's what my attributes look like:

Not sure what happened to the last post. Anyway here they are again.


Ran a zone again and stop. Still shows watering

That raw data is helpful. I'll dig in to the opcodes and try to figure it out. It does look like the vast majority of the data, including timesync are working but that "4025" for the year as part of the description for controllerTime is perplexing. controllerDate is reading it right :man_shrugging:t2:

The legacy firmware=2.10 might be a problem. seasonAdjustment shouldn't be all bits on,

When I started working on this, I was surprised at how many changes were made to the firmware that aren't universal.

1 Like

Thanks for those logs!

I have some good news and some... less than good news.

The good news is I just finished uploading v0.1.0.1 that addresses four of the items I saw in the logs.

  1. Your actual firmware is version 2.10. I didn't have a controller that old so I couldn't test against it. If you look at the debug log, you'll see that line where it says, “Detected modern firmware 3.2 (replaces legacy 2.10). In reality, you do have 2.10. That was from a logic bug that looked for an opcode response and mistook the very old response from checking for 3.x as positive when in fact, it wasn't.
  2. getAvailableStations() will not throw an error on really old firmware. The best that firmware can do is say, “All of them.”
  3. Now that I know what 2.1 firmware looks like, the seasonalAdjust() response of 65535 has been addressed. It'll max out at 100% instead. :wink:
  4. “Watering” has been somewhat addressed. That's the less than good news. Your firmware doesn't accurately report when watering is off. The best I can do is an educated guess.

Firmware ≤ 2.10 never emits updated state telemetry (no valid BF or 3F updates). The best I can do is mitigate that limitation.

Trigger Detection behavior Accuracy
My Driver (GUI/RM/WC) starts watering :white_check_mark: Immediate update :white_check_mark:
Controller/app starts watering :white_check_mark: Detected from BF=01 :white_check_mark:
Driver stops watering :warning: Heuristic fallback :gear: 80–90%
Controller/app stops watering :x: Not detected reliably :warning: Manual poll correction

If you set the Increase polling frequency during watering events parameter to true (default), the driver will poll every 5 seconds when it detects watering and, hopefully, will know when the watering stops.

If you write your own scheduling in RM/WC, the driver will be, for the most part, authoritative. If you let the controller run the programs, my suggestion is to set the refresh to 5 minutes and then, just before your scheduled program runs, change it programmatically to 1 minute.

Once the program runs, the driver should detect watering, poll every 5 seconds, and detect when it stops watering (80% accurate). Have your rule/piston go back to every 5 minutes when watering==false.

Version 0.1.0.1 is available as a direct download from Git, but I also updated HPM to pull it for you.

Please let me know what else you find, and... thanks for checking it out and the feedback.

1 Like

Thanks for the udpate. I will update and see how it goes. Crazy that the firmware for the LNK2 is not getting an update. I got the LNK2 module last March but in the tech world that is old :slight_smile:

I'll play with it more and see how it goes.

Ah... There's the rub. I have the same issue here. There are actually two pieces of firmware here.

  • The LNK/LK2 module is a Wi-Fi module only. The module does not control the system; it just provides connectivity.

  • The controllers themselves (ST8/ST8i, TM-2, ESP-me, ESP-Me3) are what we're actually communicating with. It's the firmware in the controller that matters:

Controller WiFi Module Firmware
ESP-TM2 LNK / LNK2 2.1 – 3.0
ESP-Me LNK / LNK2 2.9 – 3.2
ESP-Me3 LNK2 4.0+
ST8 / ST8i LNK 2.5 – 3.0
Feature LNK (1st Gen) LNK2 (2nd Gen)
Setup Connects to a smartphone app Connects to a smartphone app with faster Quick Pair technology, including Bluetooth
Compatibility Compatible with some residential controllers (e.g., ESP-TM2, ESP-ME, ESP-RZXe) Wider compatibility: Supports newer controllers, including commercial models like ESP-LXME2 and ESP-LXIVM
Connectivity WiFi connection Stronger, faster WiFi connection
Security Standard WiFi encryption Uses encrypted wireless communication for enhanced privacy
Advanced Features Basic remote control and alerts Includes multi-site management, advanced water-saving adjustments, remote diagnostics, and more robust notifications

My LNK2 module is firmware 3.54. That's just the Wi-Fi firmware.

I have an ESP-Me controller, which only runs firmware 2.9-3.2.

Unfortunately, the Rain Bird controllers are, from my understanding, not field upgradable, so the only way to get newer firmware (and the associated capabilities) is to buy a new controller. :slightly_frowning_face: The firmware of the LNK/LNK2 doesn't change things.

In your case, that ESP-TM2 is just an old dog that can't learn new tricks. :wink:

1 Like

Well in the prosses of trying to be smart and figure out how to try to upate firmware, I downloaded the 2.0 app. Connected and it updated the firmware of the module (looks like 4.132 but as you stated controller firm is 1.5.1.
I can access it via the app fine but now I am getting connection refused in HE. I verified the password is correct. Looking

I have to run for a while but when I get back I will see what it is or isn't doing in the HE.

The controllers are very finicky. If you ask them to do too much, you'll get 503 errors. I had to put in multiple back-off and retry routines.

I also discovered that if you are logged in to the app, HE will often time out or refuse to connect until you disconnect from their app. I've also seen it the other way, if I'm testing a bunch of things from HE, the app will either report that its busy or will just fail to connect.

Seems they never intended for multiple HTTP connects at once. :man_shrugging:t2:

1 Like

You made me look... :face_with_monocle:

This FAQ is from Rain Bird's site:

Lock Out

The encrypted password in the Rain Bird mobile app for this controller does not match the encrypted password in the LNK WiFi Module and the user attempted to connect with the wrong password more than 3 times. This locks out the controller from being accessed remotely for 15 minutes.

Controller is Busy

If you receive this message when attempting to connect to the controller, this means another smart device is currently accessing the device. Only one mobile device can connect remotely to the controller at a time.

So, yeah, they chose to not handle two HTTPS sessions at once. :slightly_frowning_face:

That kind of makes sense. They presumed the only way people would connect with the controller is through their app, and the chances of two people in the same household connecting from two mobile phones at once was slim to none.

1 Like

Which mobile app are you using, 1 or 2?

I'm using the original app even though it says its 2.17.14. (White bird, green background).

I haven't seen the need to get the later one and set up yet another cloud account for stuff like this. I'll stick with the direct connection as long as I can.

Ok, that is what I figured. As I was standing in line at the store I realized that the new app is all cloud based including the password. There is no "controller password" like there is in the old app. So I am going to move back to the old app and see what happens.

Update - Well it turns out once you have updated the firmware it is no longer compatible with the old app with no way to downgrade. So I am back on the the new app.

Hmmmmm... No good that is.

While its possible they removed local passwords and want everyone going through the cloud <LouisRossmann>”So they can monetize our usage and/or start charging a subscription for things we've already bought and paid for!”</LouisRossmann>, it sure would've been nice to know upgrading the firmware obviates all local connections by removing the password.

Rachio has already started doing this.

Maybe... Delete the controller from the legacy app, reset the module, and start the connect process over again with the old app? (YMMV) My uneducated guess here is, the older app shouldn't care or even know there is a 4.x firmware, and it will set up a local password. On the other hand, they could have written something in to the older app via an update and it will force you to use the newer app to do the setup. :man_shrugging:t2:

Unfortunately I did that and the old app does seem to care. Get a message saying that it is not compatible and have to use the new app. Pretty annoying.