Meross Garage Door Opener
GEM driver for the Meross standalone garage door openers — msg100 (single door) and msg200 (up to three doors). The opener keeps talking to the Meross cloud — the Meross mobile app continues to work alongside GEM — but every GEM command and state read flows over signed HTTP /config on the opener's LAN address.
Prerequisites
- Meross garage opener on the same LAN, already onboarded via the Meross app at least once.
- Meross cloud account credentials. Used only during the one-time
paircommand to fetch the per-account key and the device uuid; not used afterward.
Setup steps
- Add the device. Go to System → Devices → Add Device (Open Devices) and create a new device with driver
meross_garage. Setip,username(Meross email), andpassword(Meross cloud password). - Pair. Run the
paircommand. The driver logs into the Meross cloud, fetches the accountkeyand this opener'suuid, and persists them as device attributes — the accountkeyis stored encrypted, whileuuid,user_id, andmodelare plain read-only fields. After a successful pair the password can be cleared if desired. Pairing also happens automatically on the first connect whenever a username and password are present, so in practice you often don't runpairby hand at all. - Zones appear automatically. This driver auto-creates its zones on connect — one zone for an
msg100, up to three for anmsg200— so once the device pairs, the door zones show up with no further action. Each zone's address is the channel number (0for anmsg100;0/1/2for anmsg200). Auto-created zones land on the Garages subsystem (falling back to Gates only if Garages was deleted). Run thesync_zonescommand only to force a re-scan — for example after physically adding a door to anmsg200. - Verify. State polling fires every
status_interval(default 10 s) and writesstate(open/closed) onto each zone based on the door's reed switch.
Both Garages and Gates are created automatically on first boot, and garages is this driver's first subsystem hint — so the zone editor pre-selects Garages for these openers and the auto-created zones file there cleanly with no manual fix-up. If you ever build a door zone by hand, leave the subsystem on Garages so it appears on the garage control surfaces.
Attributes
Device — required
| Name | Type | Description |
|---|---|---|
ip | string | Opener LAN IP. |
username | string | Meross cloud email. Only used during pair. |
password | string (secure) | Meross cloud password. Only used during pair; can be cleared after. |
Device — optional
| Name | Type | Default | Description |
|---|---|---|---|
cloud_base | string | https://iotx-us.meross.com | Region: US/EU/AP. |
status_interval | int (ms) | 10000 | Polling cadence for door state. Minimum 2000. |
http_timeout | int (ms) | 5000 | Local HTTP request timeout. |
user_id | string (readonly) | — | Populated by pair. |
uuid | string (readonly) | — | Populated by pair. 32-char hex. Required in every SET payload. |
key | string (secure, readonly) | — | Per-account shared secret. Populated by pair; used to sign every HTTP request. |
model | string (readonly) | — | Auto-detected from hardware block (msg100 / msg200). |
Zone — address
| Field | Description |
|---|---|
address | Garage door channel number — 0 for msg100; 0/1/2 for msg200. Auto-populated by sync_zones. |
Zone — optional
| Name | Type | Default | Description |
|---|---|---|---|
open_action | string | open | Verb the garages control's Open button dispatches. The opener exposes discrete open/close primitives (not a single pulse relay), so this defaults to the open command. Stamped fill-when-empty by the driver on every synced zone — override with a different verb, an inline command, or a macro only for exotic wiring. |
close_action | string | close | Verb the garages control's Close button dispatches. Defaults to the close command. Stamped fill-when-empty; override to retarget. |
The driver stamps open_action/close_action on each zone (including zones created by an earlier version) so the garages control issues open/close directly instead of falling back to a pulse. stop_action is intentionally left unset — the opener has no mid-cycle stop, so the control correctly hides the Stop button for these zones.
Commands
| Name | Args | Description |
|---|---|---|
pair | — | One-time cloud login to fetch the account key + device uuid. Re-runnable safely (e.g. after a password change). |
sync_zones | — | Enumerate door channels on the device and auto-create matching GEM zones. |
open / on | address | Open the door on this channel. |
close / off | address | Close the door on this channel. |
stop | address | No-op — the opener does not support mid-cycle stop. Kept so generic macros don't fault. |
get_state | address | Fetch current open/closed state of one channel. |
get_all | — | Dump Appliance.System.All for diagnostics. |
Known quirks
Appliance.GarageDoor.StateSET takes the new state as a single object (not an array) and requires the deviceuuidinside it. An array shape is acknowledged (SETACK) but silently no-ops, and a missinguuidno-ops too. The driver always sends the correct shape, but commands fail with a clear error ifpairhasn't run.- Firmware response shapes vary. A single-channel
Appliance.GarageDoor.StateGET on currentmsg100firmware returnsstateas a bare object (and can time out entirely), while theAppliance.System.Alldigest returns a clean per-channel array. The driver prefers theSystem.Alldigest for discovery and normalizes the other shapes, so callers always see one consistent array. - The
msg100/msg200exposes discrete open/close commands, not a momentary pulse relay. The driver stamps per-zoneopen_action/close_actionverbs so the garages control issuesopen/closedirectly;stop_actionis left unset and the Stop button is hidden. - The opener does not support a true mid-cycle
stop. Thestopverb is implemented as a no-op so macros don't fault. - State polling reflects the door reed switch:
open=1→ zone stateopen,open=0→ zone stateclosed. There is no intermediate "moving" state on the wire. - The cloud login signs with a hard-coded Meross app secret. Meross occasionally bumps that contract; if
pairfails after a Meross app update the constant may need refreshing.
Troubleshooting
pairfails with bad credentials. Verify email/password against the Meross app and confirmcloud_basematches your region (iotx-us/iotx-eu/iotx-ap).- Commands return error
5001 "sign error". The storedkeyis stale (typically because the user changed their Meross password). Re-runpair. open/closereturns no error but the door doesn't move. Theuuidattribute is empty. Re-runpairto populate it.- Door state never updates. Confirm the reed switch is installed and seated; verify status in the Meross app.
- No zones after a connect or
sync_zones. The opener returned no channels — it is likely offline or unreachable. Confirm theipis correct and ping it; runget_alland look fordigest.garageDoorto see what the device reports. Also confirm a Garages (or Gates) subsystem still exists, since the driver needs one to file the zone under. - A door's zone exists but doesn't appear on a control screen. Auto-created zones are filed under the Garages subsystem but still have to be visible to the UI showing them — a UI bound to a site space inherits that space's zones automatically, while a hand-built UI only shows zones you explicitly add to it. Add the zone to the UI (or to the site space) where you want the door to appear.
Related documentation
- Devices — adding and configuring the opener, secure attributes, and Reload.
- Zones — the auto-created door zones and binding them to a UI.
- Subsystems — the Garages subsystem these zones live under.
- Commands — running
pair,sync_zones, and the open/close verbs from the command tester, macros, and triggers.