npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

homebridge-ratgdo-forceclose

v1.2.7

Published

HomeKit GarageDoorOpener for ratgdo-controlled Security+ 1.0 garage doors that ignores false photo-eye obstructions. Sends a single forceClose POST to the ratgdo, which performs the wall-button hold-to-close override on the device side. Requires the Hagle

Readme

homebridge-ratgdo-forceclose

A Homebridge plugin that adds a HomeKit garage-door tile (or momentary switch) for ratgdo-controlled garage doors, for cases when the photo-eye safety sensor is blocking a normal close — sun glare on the receiver, debris, or anything else.

[!IMPORTANT] v1.2.x recommended setup requires custom firmware. The single-POST hold-to-close override (the only software path that closes past a fully-blocked photo eye) requires the forked firmware Haglerd/homekit-ratgdo32 v3.4.4-forceclose.5 or later. Vanilla upstream ratgdo/homekit-ratgdo32 firmware does not have the forceClose HTTP handler. See Required firmware below.

The plugin still works against vanilla upstream firmware in legacy mode (useForceClose: false, presentAsGarageDoor: false) — same v1.0.x obstFromStatus dance — but that path only handles flickering false trips, not a fully-blocked beam.

npm version npm downloads License: MIT

Quick start: InstallConfigureGet support

What this is

A Homebridge accessory plugin that exposes one of two HomeKit accessories for your ratgdo:

  • GarageDoorOpener tile (default in v1.2.x): proper garage-door icon with live Open/Closed status. Slider to Closed triggers the firmware's hold-to-close override; slider to Open runs a normal open. State is driven by status polling so the tile updates as the door physically moves.
  • Momentary Switch (legacy v1.0.x style, set presentAsGarageDoor: false): single tap fires the close sequence, then the switch auto-resets.

The plugin runs entirely over local HTTP to ratgdo's web UI. No cloud, no MQTT, no extra dependencies.

Two operating modes

Same plugin, two HTTP-level strategies to make the door close. Pick based on what firmware your ratgdo runs.

| | forceClose mode (default, v1.2.x) | legacy obstFromStatus mode (v1.0.x compat) | |---|---|---| | Plugin config | useForceClose: true (default) | useForceClose: false | | Required firmware | Haglerd/homekit-ratgdo32 ≥ v3.4.4-forceclose.5 | Any homekit-ratgdo32 (vanilla upstream included) | | What it sends | One POST forceClose=3500 | POST obstFromStatus=true → POST garageDoorState=0 → wait → POST obstFromStatus=<original> | | Closes past fully-blocked photo eye | YES (firmware emulates wall-button hold-to-close override) | NO (only handles flickering false reads) | | Triggers ratgdo flash write / reboot | NO | YES (obstFromStatus is a persistent setting) | | Time per tap | ~25 seconds | ~30–60 seconds (TTC + recovery + close + restore) | | Close confirmation reliability | High (firmware does 2-press internally) | Medium (depends on obstruction state) |

Most users want forceClose mode. It's simpler, faster, and actually solves the photo-eye-blocked case. It's the default in v1.2.x. The only reason to use legacy mode is if you're running vanilla upstream firmware and don't want to flash a fork.

Required firmware

For default (forceClose) mode — recommended

Flash Haglerd/homekit-ratgdo32 firmware v3.4.4-forceclose.5 or later to your ratgdo32. This is a fork of the upstream ratgdo/homekit-ratgdo32 firmware with one feature added: a forceClose HTTP handler that simulates a real wall-button hold-to-close override at the Sec+1.0 protocol level — including the UL-mandated TTC warning sequence the GDO motor's override gate requires.

One-time flash: download homekit-ratgdo32-vX.X.X-forceclose.N.firmware.bin from Releases and drop it onto ratgdo's web UI Firmware Update page.

After that, OTA just works: the fork is configured with its own gitUser so ratgdo's "Check for update" button checks the fork's releases (not upstream's) and updates one-click. A daily auto-sync workflow keeps the fork rebased on top of upstream — when upstream ships a new version, the fork picks it up automatically and re-publishes with the forceClose patch applied. Maintenance is handled.

For legacy mode

Any homekit-ratgdo32 firmware works — vanilla upstream included. Set useForceClose: false and presentAsGarageDoor: false in plugin config to revert to v1.0.x behavior.

Not supported

ESPHome ratgdo firmware. The plugin uses HTTP /setgdo POSTs which are a homekit-ratgdo family thing. ESPHome ratgdo uses a different protocol stack. For ESPHome firmware, use homebridge-ratgdo-esphome or homebridge-ratgdo.

What this plugin does NOT do

To set expectations clearly:

  • It does not auto-discover ratgdo devices. You configure one accessory per door with the IP/host explicitly. (Most homes have one garage door; this is fine.)
  • It does not work over the cloud. Plugin → ratgdo communication is local-network only. (HomeKit access from outside your network still works via your HomeKit hub — Apple TV / HomePod / iPad — like any other HomeKit accessory.)
  • It does not work with ESPHome ratgdo firmware. This plugin requires the homekit-ratgdo / homekit-ratgdo32 firmware which exposes the POST /setgdo HTTP endpoint. ESPHome ratgdo uses a different protocol stack — see Required firmware above.
  • It does not bypass the GDO motor's own UL safety logic unless the firmware fork's hold-to-close override engages it. Even with forceClose mode, if the motor's own internal photo-eye sensor (separate from ratgdo's pin) sees a fully-blocked beam, it will reverse the door mid-close. The fork's firmware emulates the wall-button hold-to-close pattern that the motor recognizes as "user is overriding safety" — same UL-approved override the wall button gives you. If your install doesn't honor wall-button hold-to-close either, no software can fix it.
  • It does not pair with HomeKit directly. Goes through Homebridge. (For native HomeKit pairing, the firmware does that itself — separate accessory.)

Two ways to use this

This repo offers two delivery mechanisms for the same underlying behavior:

  • Homebridge plugin (the rest of this README) — full HomeKit integration with a tappable switch in the Home app, remote access via your HomeKit hub, configurable cooldown, optional digest auth.
  • HomeKit Shortcut — no Homebridge required; build a one-off button in the iOS Shortcuts app that fires the same three-POST sequence over the local network. Build instructions: shortcut/README.md.

Both options do exactly the same thing on ratgdo's side. See the comparison table further down to pick which one fits your setup.

The problem it solves

Liftmaster and Chamberlain garage doors have an infrared photo-eye safety sensor at the bottom of the rails. The receiving eye can be blinded by direct sunlight at low sun angles (typically morning or late afternoon depending on which way your garage faces). When that happens, the opener registers a false obstruction and refuses to close.

ratgdo respects that obstruction signal and will not send a close command while the obstruction flag is asserted. This is correct, safe default behavior — but it means HomeKit-initiated closes silently fail during sun-glare windows.

The traditional workaround is to walk to the garage and hold the wall control button until the door closes (which bypasses the photo eye on most opener models). This plugin gives you a HomeKit-tappable software equivalent: it temporarily changes ratgdo's obstruction-source setting from "the sensor pin" to "GDO status messages" — the GDO itself isn't false-tripped, only the wire from the photo eye is — sends the close, then restores the setting.

Compatibility

Firmware — this plugin requires homekit-ratgdo family firmware:

Garage-door opener — works with any ratgdo-compatible opener:

  • Tested on Liftmaster Security+ 1.0 with homekit-ratgdo32 v3.4.4.
  • Should work on Security+ 2.0 too but has not been verified.

Runtime — Homebridge 1.6+ and Node.js 18+.

Safety warning

This plugin bypasses the obstruction sensor's effect on ratgdo. Only use it when you can directly see the door and have confirmed nothing is in the path. The obstruction sensor exists for a reason — it stops a closing door from crushing pets, children, or property. Tapping this switch is the equivalent of holding the wall-control button down: the safety check is suppressed for the duration of the close.

Do not put this switch in an automation, scene, or shortcut that runs without you watching. The plugin enforces a configurable cooldown to prevent fat-finger re-triggers, but cooldown is not a substitute for paying attention.

If your photo eye is being false-tripped frequently enough that you need this plugin, consider also installing a sun shroud or hood over the receiver eye — that's the actual fix.

Plugin vs. Shortcut: which should I use?

| Feature | Homebridge Plugin | HomeKit Shortcut | |---|---|---| | Appears as a HomeKit switch in the Home app | Yes | No (lives in Shortcuts app, can be added to home screen / Siri / Control Center) | | Works from outside your local network (cellular, etc.) | Yes (via HomeKit hub) | No (LAN only) | | Shared with everyone in your Home automatically | Yes | No (each user builds their own) | | Requires Homebridge running on a Pi/server | Yes | No | | Setup time | ~10 min (install npm pkg, edit config) | ~5 min (build in Shortcuts app) | | Supports ratgdo "Require Password" (digest auth) | Yes | No | | Triggerable by Siri / HomePod | Indirectly (via Home app voice) | Directly ("Hey Siri, force close garage") | | Triggerable by HomeKit automation | Yes (but don't — see safety) | No |

If you already run Homebridge, the plugin is the cleaner integration. If you don't, the Shortcut gets you the same close-the-door behavior with a five-minute build and no server. Build steps for the Shortcut: shortcut/README.md.

Installation

Tip: Run this plugin as a child bridge if your Homebridge UI supports it (most modern setups do). Right-click the plugin in the Plugins tab and choose Bridge Settings → Run as a Child Bridge. This isolates the plugin in its own process so a config error or crash can't take down everything else on your bridge. Recommended by the Homebridge maintainers for any plugin that talks to a network device.

Method 1 — Homebridge UI (recommended)

  1. Open the Homebridge UI in your browser.
  2. Go to the Plugins tab.
  3. Search for homebridge-ratgdo-forceclose (or use the search bar's three-dot menu → Install Plugin and paste the package name).
  4. Once installed, click the plugin's Settings (cog) icon and fill in ratgdoHost (and username / password if your ratgdo requires auth).
  5. (Recommended) right-click the plugin tile → Bridge Settings → toggle Run as a Child Bridge.
  6. Save, then restart the child bridge (or Homebridge itself) using the prompt at the top of the UI.

After restart, the Force Close Garage switch appears in the Home app under the Homebridge bridge.

Method 2 — Install via npm CLI

sudo npm install -g homebridge-ratgdo-forceclose
sudo hb-service restart

Method 3 — Install from a local clone

git clone https://github.com/Haglerd/homebridge-ratgdo-forceclose.git
cd homebridge-ratgdo-forceclose
sudo npm install -g .
sudo hb-service restart

Updating

  • Via Homebridge UI: Plugins tab → click the plugin's Update button when one is available.
  • Via CLI: sudo npm update -g homebridge-ratgdo-forceclose && sudo hb-service restart.

Configuration

Minimal config

{
  "accessories": [
    {
      "accessory": "RatgdoForceClose",
      "name": "Force Close Garage",
      "ratgdoHost": "http://192.168.1.50"
    }
  ]
}

That's enough to get a working switch. Replace 192.168.1.50 with your ratgdo's actual IP or hostname.

Full config

{
  "accessories": [
    {
      "accessory": "RatgdoForceClose",
      "name": "Force Close Garage",
      "ratgdoHost": "http://192.168.1.50",
      "username": "admin",
      "password": "your-password-here",
      "settingKey": "obstFromStatus",
      "bypassValue": true,
      "normalValue": false,
      "closeWaitMs": 18000,
      "cooldownMs": 20000
    }
  ]
}

Configuration reference

| Key | Type | Default | Description | |---|---|---|---| | name | string | "Force Close Garage" | The HomeKit name for the switch. | | ratgdoHost | string | (required) | Base URL of your ratgdo, e.g. http://192.168.1.50. The http:// prefix is added if you omit it. | | username | string | null | Only required if you've enabled "Require Password" in ratgdo's settings. | | password | string | null | Paired with username. The plugin uses HTTP Digest auth (which is what ratgdo uses). | | settingKey | string | "obstFromStatus" | Which ratgdo setting to toggle. Defaults to obstFromStatus. Switch to pinBasedObst and flip the bypass/normal booleans if the default doesn't work for your firmware. | | bypassValue | boolean | true | Value POSTed to settingKey before the close command. For obstFromStatus: true = use status messages, ignore the pin (the sun-flare false trip). | | normalValue | boolean | false | Value POSTed to settingKey after the close command — your normal pre-tap setting. | | closeWaitMs | integer | 18000 | Milliseconds to wait between sending close and restoring settingKey. Should comfortably exceed your door's full close duration. Min 1000, max 60000. | | interStepMaxWaitMs | integer | 15000 | Maximum ms to wait for ratgdo's HTTP server to be responsive between Step 1 and Step 2. The plugin actively polls GET /status.json every 250ms and proceeds the moment ratgdo answers — so on a healthy ratgdo Step 2 fires in <500ms. The 15s default is a ceiling for the worst case (firmware briefly crashes/restarts after a config-change POST). Min 1000, max 60000. | | cooldownMs | integer | 20000 | Minimum milliseconds between consecutive force-close triggers. Min 0, max 120000. |

How it works

On every tap of the switch, the plugin runs a four-step POST sequence against ratgdo's /setgdo endpoint:

  1. POST settingKey=bypassValue — temporarily change ratgdo's obstruction source. With the default obstFromStatus=true, this means "stop reading the sensor pin, only listen for obstruction in the GDO's own status messages." A short 300ms pause follows so the firmware has time to apply the new setting.
  2. POST garageDoorState=0 — the close command itself. Because the obstruction source has been swapped, the false-tripped pin no longer blocks ratgdo from issuing close.
  3. Wait closeWaitMs — give the door time to finish its travel cycle. Default 18s is safe for most residential doors.
  4. POST settingKey=normalValue — restore the original setting (default obstFromStatus=false, i.e. read obstruction from the pin again). This step runs in a finally block, so even if step 2 or 3 throws, the bypass setting is restored before the function returns. If step 4 itself fails, the plugin logs a CRITICAL warning telling you to restore the setting manually in ratgdo's web UI.

The setting being toggled (obstFromStatus) corresponds to the "Get obstruction from GDO status messages" checkbox on ratgdo's settings page. If you want to see what state your ratgdo is in, that's the field to check.

Troubleshooting

  • The switch flips on and immediately flips off but the door doesn't move. Check Homebridge logs (sudo hb-service logs) for a non-200 response from /setgdo or a digest-auth failure. If you've enabled "Require Password" on ratgdo, make sure username and password are set in the plugin config.

  • The switch fires the sequence but the door still doesn't close. This means the obstruction is being seen by the opener itself, not just propagated through ratgdo. Try the inverse setting: change settingKey to pinBasedObst and flip the booleans — bypassValue: false, normalValue: true. That tells ratgdo "stop reading the obstruction pin entirely" instead of just changing the source.

  • Neither setting works. The photo eye is being blinded at the hardware level — ratgdo can't help here because the obstruction signal is already locked in at the opener's logic board. The actual fix is a sun shroud or hood over the photo-eye receiver (search "garage door photo eye sun shield"). A piece of black PVC pipe works in a pinch.

  • Where to look at logs. Homebridge: sudo hb-service logs. ratgdo's own log: http://YOUR-RATGDO-IP/showlog. The plugin logs each step of the four-step sequence with [Force Close Garage] prefixes (or whatever name you configured).

  • Cooldown active error. You tapped the switch too soon after the previous tap. Wait for the configured cooldownMs to elapse. Default is 20 seconds.

  • HomeKit Home app still shows "Open" after a successful Force Close. The door is actually closed — ratgdo updates its target_door_state HomeKit characteristic correctly when our plugin issues the close, but iOS Home app aggressively caches accessory state and doesn't always refresh the UI when changes come from outside HomeKit's command path (i.e., from the plugin's HTTP POST instead of a tap on the regular ratgdo tile). To force a refresh: pull down on the room view in the Home app, or kill and reopen the app. This is an iOS Home app limitation, not a plugin or ratgdo firmware bug. Verified by checking ratgdo's internal log — Door state changing from Closing to Closed (target Closed) confirms the notify path fired, the iOS UI just hadn't pulled the update.

Releasing (maintainer notes)

Releases are published to npm automatically by .github/workflows/publish.yml when a tag matching v* is pushed. To cut a release:

# 1. Bump "version" in package.json (e.g. 1.0.0 → 1.0.1) and commit
git commit -am "Release v1.0.1"

# 2. Tag the commit
git tag v1.0.1

# 3. Push both
git push && git push --tags

The workflow then runs npm publish --access public --provenance against the tagged commit. The --provenance flag attaches a build attestation that links the npm tarball back to the exact GitHub Actions run, visible as an "Attested" badge on the npm package page.

The workflow refuses to publish if the git tag version doesn't match package.json — that's a guard against tagging v1.0.2 while forgetting to bump package.json, which would leave the registry and git history out of sync.

You can also trigger the workflow manually from the Actions tab via workflow_dispatch (publishes whatever's currently in package.json).

Authentication: the workflow uses npm Trusted Publishing — no NPM_TOKEN secret in GitHub. Instead, npm is configured to trust this specific repo + workflow combination via OIDC, and GitHub Actions issues a short-lived OIDC token at run time. There's no long-lived secret to leak or rotate.

One-time setup (after the workflow lands on main):

  1. Go to https://www.npmjs.com/package/homebridge-ratgdo-forceclose/access
  2. Scroll to Trusted PublisherAdd trusted publisher
  3. Choose GitHub Actions and fill in:
    • Organization or user: Haglerd
    • Repository: homebridge-ratgdo-forceclose
    • Workflow filename: publish.yml
    • Environment name: (leave blank unless you set up a deployment environment)
  4. Save.

That's it. Push a v* tag and the workflow publishes — no secrets configured anywhere.

Plugin architecture (for Verified-plugin reviewers)

This is a static accessory plugin (pluginType: accessory) rather than a dynamic platform. The choice is deliberate:

  • One ratgdo per garage; users have one IP / one accessory. No discovery is needed (or possible without rewriting the firmware) — config is explicit per accessory block.
  • Existing pairings keep their HomeKit accessory identifiers across plugin upgrades because static accessories don't manipulate cached UUIDs.
  • The accessory exposes a single primary service (GarageDoorOpener by default, Switch in legacy mode) plus optional secondary services (Reboot, Obstruction sensor, Motion sensor) that compose well as a single HomeKit accessory tile group.

If you operate multiple ratgdo doors, add multiple accessory entries in your Homebridge config.json — each with its own name and ratgdoHost. There is no platform-level state shared between them.

Support

Issues, feature requests, and questions: https://github.com/Haglerd/homebridge-ratgdo-forceclose/issues

When opening an issue, please include:

  • Plugin version ([email protected])
  • Homebridge version + Node version
  • ratgdo firmware version (visible at the top of http://<ratgdo-ip>/)
  • The relevant section of your Homebridge log around the failure
  • Whether you're on the Haglerd/homekit-ratgdo32 fork firmware (recommended) or vanilla upstream

For ratgdo firmware issues (not plugin issues): the firmware fork lives at https://github.com/Haglerd/homekit-ratgdo32 and has its own issue tracker. The two repos are separate; use the one that matches your problem.

This is a personal-time project; expect best-effort response within a few days. PRs welcome.

License

MIT — see LICENSE.

Disclaimer

This plugin is not affiliated with ratgdo, Paul Wieland, Chamberlain, Liftmaster, Apple, or Homebridge. The author provides no warranty and assumes no liability for property damage, injury, or other consequences of using this software (see the LICENSE file for the full terms). Use at your own risk, and only with a clear line of sight to the door.