Chamberlain MYQ Garage Door Control

The following is a quick high level of how I implemented automated control for my Chamberlain MYQ based garage door. When I bought the new door opener, I incorrectly assumed it contained the automated control. I unfortunately found out that you have to buy the gateway for a $100 dollars. I wanted to find a cheaper option for this, and the below is the result.

Items/Methods Used:
Particle Photon
2xSPDT-Submini Roller Lever Switch (Radioshack 275-0017)
N-Channel MOSFET
Chamberlain Smart Control Panel - 41A7305-1 (Came with Garage Door Opener)
MQTT for garage state(Open/Closed) updates
Batch file to call curl

First, please use this with caution as I hacked my way through it using what I had available to me. I am sure there may be better methods to do this, so feel free to comment and provide feedback.


  • This uses the particle api via the web. I have had no issues yet, but intend to move to local network control for the photon in the future.

NOTE: Code and Openhab items/sitemap updated to reflect two switches. I have not updated the picture, but just duplicate the current pictured switch on a different pin for the second one.

Particle Photon code:

//The following utilized pin D7 of the particle to short the pins on a button of the Chamberlain MYQ multi function control
//following a function call from the particle web api curl command. Pin D1 is connected to a roller switch that detects 
//when the door is open and sends a publish message to a mosquitto mqtt server.

// This #include statement was automatically added by the Particle IDE.
#include "MQTT/MQTT.h"

//register callback
void callback(char* topic, byte* payload, unsigned int length);

// connection string for mqtt
byte server[] = { xxx,xxx,x,xxx }; //IP of mqtt server
MQTT client(server, 1883, callback); // port of mqtt server

//establish variables
int garageStateOpen = 0; //initial state of the garage is zero unless 1 is detected
int garageStateClosed = 0;
int stateTrackerOpen = 0;
int stateTrackerClosed = 0;
int garageButton = D7; //using digital pin 7 to mimic short on chamberlain panel
int garageSwitchOpen = D1; //using digital pin 1 for roller switch open
int garageSwitchClosed = D0; //using ditital pin 0 for roller switch closed

void setup() {

// connect to the mqtt server

//publish variable to api
Spark.variable("stateOpen", &garageStateOpen, INT);
Spark.variable("stateClosed", &garageStateClosed, INT);

//setup pinmodes
pinMode(garageButton, OUTPUT);
pinMode(garageSwitchOpen, INPUT_PULLDOWN); //using INPUT_PULLDOWN to stop flapping/false HIGHs
pinMode(garageSwitchClosed, INPUT_PULLDOWN);

//establish spark function gd to be called by the particle web api
Spark.function("gd", gdToggle);

//set D7 to High as the Chamberlain button works via a short.
digitalWrite(garageButton, HIGH);


void loop() {
//read state of D1 to determine state of switch
    garageStateOpen = digitalRead(garageSwitchOpen);
    garageStateClosed = digitalRead(garageSwitchClosed);
//monitor state of switch and publish to mqtt. Use a tracker variable comparison to only send update when the state has changed.
if (client.isConnected()) {
   else {
   if(garageStateOpen!=stateTrackerOpen)  //this determines if there has been a change in state
       stateTrackerOpen=garageStateOpen; //update the tracker variable to the new state
   if (client.isConnected()) {
        //mqtt publish based upon the state
        if (garageStateOpen==0){
        if (garageStateOpen==1) {
    if(garageStateClosed!=stateTrackerClosed)  //this determines if there has been a change in state
       stateTrackerClosed=garageStateClosed; //update the tracker variable to the new state
   if (client.isConnected()) {
        //mqtt publish based upon the state
        if (garageStateClosed==0){
        if (garageStateClosed==1) {

// spark function that is called from api with inputs
int gdToggle(String command) {
    if (command=="buttonpush") {
        digitalWrite(garageButton, LOW); //this causes a short and mimics a physical button push on the chamberlain panel
        delay (1000);
        digitalWrite(garageButton, HIGH); //set back to HIGH to stop the short
        return 1;
    else {
        return -1;

// recieve message but do nothing, the only use publish, not subscribe
void callback(char* topic, byte* payload, unsigned int length) {

Openhab Items:

Switch garageButton "Garage" <garagedoor> {autoupdate="false",imperihab="room:Garage,label:Garage Button"}
String garageState "Garage Door [%s]" <garagedoor> {imperihab="room:Garage,label:Garage"}
Switch garageStateOpen "Garage Open?" <garagedoor> {mqtt="<[mosquitto:/home/garage/garageStateOpen:state:default]"}
Switch garageStateClosed "Garage Closed?" <garagedoor> {mqtt="<[mosquitto:/home/garage/garageStateClosed:state:default]"}

Openhab Sitemap:

Frame label="Garage Door"{
	Switch item=garageButton label="Garage" mappings=[ON="GO"]
	Text item=garageState

Garage State Rule:

rule "Determine Status of Garage Door"
 	Item garageStateOpen changed or
 	Item garageStateClosed changed
 	if (garageStateOpen.state == ON){
 	else if (garageStateClosed.state == ON){
 	else {
 		postUpdate (garageState,"Ajar")


To send curl request to the particle api, I had to use the executeCommandLine function in a rule:

rule "Control Garage Door"
		Item garageButton received command ON

openhab gd.bat file called by rule:

c:\curl\curl \ -d access_token=myaccessid \ -d params=buttonpush
1 Like

I would go ahead and open this up to any garage door. I have used a similar method to open my garage door. The only real differences is that I use a relay in line with the opener button so I don’t have to mess with whatever voltage that thing is running and I use an ultrasonic sensor for the distance from the ceiling to the floor/door to determine if it is open or closed.

1 Like

Edited initial post to reflect addition of a second state switch. This allows confirmation of whether the door fully opened for fully closed. I did not update picture, but second switch would be connected just like first, just on another pin. In my case, PIN 0.

Update on my solution for those interested. The solution has been working flawlessly since i implemented in September, other than a few issues with the placement oft he lever switches. Sonar may be something i look at in the future to remove the mechanical aspect of the lever switches. The Particle photon has been perfect with no issues, resets or changes needed… up until recently.

As i am moving my OH1 items to OH2, i needed to update my Particle photon code to point to a different MQTT server IP. As I attempted this, I received errors in the code due to an update to the particle language. No real big issues, just a pain. I made the updates, and attempted to test with no success.

The BAD:
I went down to check on the status of the photon and noticed that is was flashing red. Ok, needs a reboot I figured. Unfortunately no, long story short, it was performing and OTA firmware update and by stopping it in the middle, i bricked my photon. I of course did not find this out until checking the particle forums to see what happened. Apparently the code update initiates an automatic OTA firmware update. Fine and good, unless you are unaware and if it has no ability to reset. Some folks in the forum were able to get into command line mode or safety mode and fix the issue. I was not.

Upon contacting Particle, they were quick to respond, acknowledged the lacking documentation issue they have, and provided a few options for me to try, but in the end agreed to replace the device. I was shipped the new one, arrived within a few days, and up and running again.

In the end, they made a bad choice in how they deployed their OTA, but stood behind their choice and made it right. I appreciated the level of customer service, and as such, would continue to recommend them as a solution.

Particle Photon ran for 6 months perfectly, OTA update interruption bricked it, good customer service and replacement, a few days later, running again.


If you are using a Particle Photon, you could probably use the Garadget binding in its current form to monitor and control the device using the Particle REST API. The binding config string is composed of < to read device variables or > to call device functions, and in [brackets] the Particle device ID, a hash symbol #, followed by either the device variable or function name. The binding supports all item types. So this is another way to integrate Particle Photon or other Particle devices into openHAB, regardless of on which networks the device is installed.

Thanks, I saw that as I was perusing the forums, i might give it a go as i would like to get away from using the .bat file method to send the curl commands from OH1.


Thanks #watou, working great. This helped me mark off an item on my OH2 migration list.

1 Like