Chamberlain/Liftmaster MyQ Operation Plugin

[quote=“Jamr, post:40, topic:170458”][quote=“tb001, post:39, topic:170458”]I bought a couple of the retrofit kits to take care of my garage doors, so crossing my fingers there’s a plug in soon.

Was hoping I could add one to our gate as well–any thoughts on whether this would work? Seems like it should, but not obvious how to do it…[/quote]

TB001 Tell me about your gate setup and what you want to accomplish.
BTW, we do now have a unboxing and installation video of the Ecolink tilt garage door sensor is anyone is interested.[/quote]

Jamr, thanks for asking. We have what I think is a set of LA400 swing arms powering our gate–they are, unfortunately, not backward compatible with MyQ, so was hoping I could use the same MyQ retrofit kit for the garage doors on the gate operator instead. It seems like there should be a way to do this, but it’s definitely a non-standard application. We basically just want to be able to open and close the gates remotely and know if they’ve been left open, ideally through Vera, though we’d be happy to use a third party app at this point. Any suggestions would be welcome.

it appears that the documentation from when I first looked at it has grown or perhaps my memory isn’t so good.
but yes, I’m able to get my token and interact with the service – if the basic operations: state, open door, close door can be derived, would a vera plugin be extremely difficult?

Hi macrho,

Are you at a position where you can share your C# code? I have a LiftMaster MyQ at home too (+ the Internet Gateway). I really would like to see it in action with my own eyes!

Thanks.

If I get it working, sure - I basically was using the URLs displayed above to get my token and then to work with subsequent methods via the URL. I’d like to get a basic set of test cases going:

What is the door status: open/closed/closing/opening
Close door
Open door

I’m just using what other folks have displayed but it would be very cool if this could be shown to work and then be wrapped into a plugin.

[quote=“tb001, post:41, topic:170458”][quote=“Jamr, post:40, topic:170458”][quote=“tb001, post:39, topic:170458”]I bought a couple of the retrofit kits to take care of my garage doors, so crossing my fingers there’s a plug in soon.

Was hoping I could add one to our gate as well–any thoughts on whether this would work? Seems like it should, but not obvious how to do it…[/quote]

TB001 Tell me about your gate setup and what you want to accomplish.
BTW, we do now have a unboxing and installation video of the Ecolink tilt garage door sensor is anyone is interested.[/quote]

Jamr, thanks for asking. We have what I think is a set of LA400 swing arms powering our gate–they are, unfortunately, not backward compatible with MyQ, so was hoping I could use the same MyQ retrofit kit for the garage doors on the gate operator instead. It seems like there should be a way to do this, but it’s definitely a non-standard application. We basically just want to be able to open and close the gates remotely and know if they’ve been left open, ideally through Vera, though we’d be happy to use a third party app at this point. Any suggestions would be welcome.[/quote]

This should be doable.
If your gate is close enough to the home to get the Z-Wave signals.
If not then you will have to run some wiring from the gate location to the home where Z-Wave communication with your controller is possible.

If your gate is close enough to communicate with the controller, attach our RM10 to the gate controller normally open trigger input and plug the appliance module to the 110vac power source for the gate.
Then attach the door sensor to the gate.
Include the two to your Vera and you are set.

If your gate is too far away from the home to receive your Z-Wave signals, you will have to run wires from the gate location into the home where your other Z-Wave components are.
You will need a pair for the gate sensor and a pair for the gate trigger.
Once you get the 2 pairs into the home attach them to the RM10 and the appliance module and the other to the input for the door sensor.
Then connect the other ends to the normally open trigger input of the gate controller and a outdoor gate or door switch mounted to the gate.
Include the two to your Vera and you are set.

If you cant get wires to the house you might be able to use some Z-Wave range extenders or possibly trigger with a relay the remote control you use in your car but then things become kind of cheesy. I prefer the wired route as it keeps the Z-Wave components out of the weather and in the home close to the controller. If you need to change the batteries in the door sensor it is not such a hassle as finding it out in the dirty gate controller area.

I realize running wires is a pain, but if your gate guys was competent in the least they should have run conduit between the gate controller and the home. If so, there is a chance you can fish some wires to the gate area.
Good luck.

Jamr, thanks for taking time to walk through our application! one question-- would we still be able to use the keypad/remote controllers we have now? Our z-wave should reach the gate, so I think we’ve got that covered, though I haven’t put it to the full test yet.

The scenario I described will not affect your keypad or remote controls UNLESS you are already using the NO trigger input on the gate controller for either the remote or the keypad already. Your gate controller may have more than one input on it. If it does, please use one of the unused inputs.
If the controller has only one trigger input and it is being used, you may need to use some diodes when installing the RM10. It may be that the other trigger devices (Keypad and remote) wont care that there is a short on their outputs or it may be that they will malfunction. You may have to call their manufactures and ask if a direct short on the output will harm of make their products malfunction. I would probably put diodes on anyway.

I should have asked earlier. What is the model of the gate controller?

[quote=“jeff3lo, post:43, topic:170458”]Hi macrho,

Are you at a position where you can share your C# code? I have a LiftMaster MyQ at home too (+ the Internet Gateway). I really would like to see it in action with my own eyes!

Thanks.[/quote]

A little progress but I’m a complete and utter hack at this:

I can use JSON.NET to get a Security Token.

With that, I can then inspect my devices and their associated details

I’m not having any luck working with the setDeviceAttribute, which would allow me to open or close my door…

some info here: liftmaster_myq/apiary.apib at 30b7acfe49bbf3819ea69d42f06733e59671b5ec · pfeffed/liftmaster_myq · GitHub

## Toggle Device State [/Device/setDeviceAttribute]
### Open or close the door (and turn lights on/off?) [PUT]
        
        {
            "AttributeName":"requestdevicestatus",
            "DeviceId":"987654321098",
            "ApplicationId":"APPID-FROM-CONSTANTS",
            "AttributeValue":"1",
            "SecurityToken":"YOUR-TOKEN"
        }

I’m getting a 404 error or something like that, I’m attempting to PUT as opposed to GET this data.
As I said, I’m a hack at this. Hoping an epiphany might come or someone who knows this stuff might chime in :slight_smile:

I can open and close my garage door now by JSON
What I’ve written is very ugly, will probably offend many but it does allow my doors to be opened/closed
I was just messing around with each end point and seeing what I could find, so it’s all hacked together - you’ve been warned

  const string appId = "Vj8pQggXLhLy0WHahglCD4N1nAkkXQtGYpq2HrHD7H1nvmbT55KqtN6RSF4ILB%2fi";


public static string login(string Username, string Password)
    {
      var client = new WebClient();
      string requestURL = "https://myqexternal.myqdevice.com/Membership/ValidateUserWithCulture?appId="+ appId +"&securityToken=null&username=" + Username + "&password=" + Password + "&culture=en";
      var response = client.DownloadString(new Uri(requestURL));
      JObject o = JObject.Parse(response);

      int ReturnCode = Convert.ToInt32(o["ReturnCode"]);
      string SecurityToken = string.Empty;
      // All ok

      if (ReturnCode == 0)
      {
        SecurityToken = o["SecurityToken"].ToString();
        Console.WriteLine("Success, your token is " + SecurityToken);
      }
      else
        Console.WriteLine("Login failure.");

      return SecurityToken;
    }

So above, I pass in my username and password and I’ve got my token

    public static void getInfo(string SecurityToken)
    {
      StringBuilder sbOutput = new StringBuilder();
      var client = new WebClient();
      string requestURL = "https://myqexternal.myqdevice.com/api/UserDeviceDetails?appId=" + appId + "&securityToken=" + SecurityToken;
      var response = client.DownloadString(new Uri(requestURL));
      JObject o = JObject.Parse(response);
      foreach( var item in o)
      {
        sbOutput.Append(item.Key + " -- " + item.Value.ToString());
        sbOutput.Append(Environment.NewLine);
        
      }
//      Console.WriteLine(response.ToString());
      System.IO.File.WriteAllText("c:\\results2.txt", sbOutput.ToString());

    }

The output here gives me a listing of all my devices, from here I found one of my garage door openers:

{
    "MyQDeviceId": xxxx,
    "ParentMyQDeviceId": xxxx,
    "MyQDeviceTypeId": 2,
    "MyQDeviceTypeName": "GarageDoorOpener",
    "DeviceId": "xxxxx",
    "DeviceName": "CG08000E1F6A",
    "TypeId": 47,
    "TypeName": "Garage Door Opener",
    "UserName": "xxxx",
    "UserConnectServerId": 0,
    "UserCountryId": 0,
    "Attributes": [

I then used my garage door opener deviceId to open or close:

    public static void doSomething(string SecurityToken)
    {
      StringBuilder sbOutput = new StringBuilder();
      var client = new WebClient();
      client.Headers[HttpRequestHeader.ContentType] = "application/json";

      StringBuilder sbPostData = new StringBuilder();
      sbPostData.Append("{" );
      sbPostData.Append(Environment.NewLine);
      sbPostData.Append("  \"AttributeName\": \"desireddoorstate\",");
      sbPostData.Append(Environment.NewLine);
      sbPostData.Append("  \"DeviceId\": \"XXXXXXX\",");
      sbPostData.Append(Environment.NewLine);
      sbPostData.Append("  \"ApplicationId\": \"" + appId + "\",");
      sbPostData.Append(Environment.NewLine);
      sbPostData.Append("  \"AttributeValue\": \"0\",");
      sbPostData.Append(Environment.NewLine);
      sbPostData.Append("  \"SecurityToken\": \"" + SecurityToken + "\"");
      sbPostData.Append(Environment.NewLine);
      sbPostData.Append("}");
      sbPostData.Append(Environment.NewLine);
      Console.WriteLine(sbPostData.ToString());


      var response = client.UploadString("https://myqexternal.myqdevice.com/Device/setDeviceAttribute","PUT", sbPostData.ToString());
      JObject o = JObject.Parse(response);

      foreach (var item in o)
      {
        sbOutput.Append(item.Key + " -- " + item.Value.ToString());
        sbOutput.Append(Environment.NewLine);
      }
      Console.WriteLine(sbOutput.ToString());
    }

[quote=“Jamr, post:47, topic:170458”]The scenario I described will not affect your keypad or remote controls UNLESS you are already using the NO trigger input on the gate controller for either the remote or the keypad already. Your gate controller may have more than one input on it. If it does, please use one of the unused inputs.
If the controller has only one trigger input and it is being used, you may need to use some diodes when installing the RM10. It may be that the other trigger devices (Keypad and remote) wont care that there is a short on their outputs or it may be that they will malfunction. You may have to call their manufactures and ask if a direct short on the output will harm of make their products malfunction. I would probably put diodes on anyway.

I should have asked earlier. What is the model of the gate controller?[/quote]

Thanks Jamrs. I’m out of town now, but will check over the weekend and see if it looks like something I can handle. Crossing my fingers that it’s fairly straightforward!

I cleaned up the code a little bit… slightly better. You’ll need json.net. This is .NET 4.5 and I was using VS 2013
How hard would this be to make into a plugin? All the methods here are working:

login - no idea about how long the token is good for
getDeviceId - would only need to be use once to populate device ids for each garage door opener
getDeviceStatus - Could feed the open/closed/closing/opening status for the device
changeDeviceStatus - Open or Close the door

I’ve tested on my doors and it all works

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Utilities;
using System.Net;
using System.Web.Script.Serialization;

namespace myQ
{
  class Program
  {
    const string appId = "Vj8pQggXLhLy0WHahglCD4N1nAkkXQtGYpq2HrHD7H1nvmbT55KqtN6RSF4ILB%2fi";

    static void Main(string[] args)
    {
      string strToken = login("", "");
      string strDeviceId = getDeviceId(strToken,"Garage Door Opener Left");
      string GarageStatus = getDeviceStatus(strToken, strDeviceId);
      string GarageStatusChange = changeDeviceStatus(strToken, strDeviceId,"0");
    }

    public static string login(string Username, string Password)
    {
      string strToken = string.Empty;
      var client = new WebClient();
      var uri = new Uri(string.Format("https://myqexternal.myqdevice.com/Membership/ValidateUserWithCulture?appId={0}&username={1}&password={2}&culture=en",
                                      appId, Username, Password));
      var response = client.DownloadString(uri);
      JObject o = JObject.Parse(response);
      // Check our returnCode, 203 appears to be a failure while 0 is a success
      if (Convert.ToInt32(o["ReturnCode"]) == 0)
        strToken = o["SecurityToken"].ToString();
      return strToken;
    }

    public static string getDeviceId(string SecurityToken, string GarageDoorName)
    {
      string strDeviceId = string.Empty;
      var client = new WebClient();
      var uri = new Uri(string.Format("https://myqexternal.myqdevice.com/api/UserDeviceDetails?appId={0}&securityToken={1}",
                                      appId, SecurityToken));
      var response = client.DownloadString(uri);
      JObject o = JObject.Parse(response);
      int numDevices = o["Devices"].Count();
      for (int i = 0; i < numDevices; i++)
      {
        // It appears that a TypeId of 47 is an actual garage door opener
        if( Convert.ToInt32(o["Devices"][i]["TypeId"])==47 )
        {
          // Probably a bad idea hard coding array position
          string strGarageDoorName = o["Devices"][i]["Attributes"][7]["Value"].ToString();
          strDeviceId = o["Devices"][i]["DeviceId"].ToString();
          if (strGarageDoorName == GarageDoorName)
            break;
        }
      }
      return strDeviceId;
    }

    public static string getDeviceStatus(string SecurityToken, string GarageDoorDeviceId)
    {
      string strDeviceId = string.Empty;
      var client = new WebClient();
      var uri = new Uri(string.Format("https://myqexternal.myqdevice.com/Device/getDeviceAttribute?appId={0}&securityToken={1}&devId={2}&name={3}",
                                      appId, SecurityToken, GarageDoorDeviceId,"doorstate"));
      var response = client.DownloadString(uri);
      JObject o = JObject.Parse(response);
      Console.WriteLine(o.ToString());
      string curState = o["AttributeValue"].ToString();

      // Statuses found: https://github.com/pfeffed/liftmaster_myq/blob/master/lib/liftmaster_myq/device/garage_door.rb
      string result = string.Empty;
      if (curState == "1")
        result = "Open";
      else if (curState == "2")
        result = "Closed";
      else if (curState == "4")
        result = "Opening";
      else if (curState == "5")
        result = "Closing";
      else
        result = curState + " is an unknown state";

      return result;
    }


    // 1 is for open, 0 is for close
    public static string changeDeviceStatus(string SecurityToken, string GarageDoorDeviceId, string state)
    {
      string json = new JavaScriptSerializer().Serialize(new
      {
        AttributeName = "desireddoorstate",
        DeviceId = GarageDoorDeviceId,
        ApplicationId = appId,
        AttributeValue = state,
        SecurityToken = SecurityToken
      });

      var client = new WebClient();
      client.Headers[HttpRequestHeader.ContentType] = "application/json";
      var response = client.UploadString("https://myqexternal.myqdevice.com/Device/setDeviceAttribute", "PUT", json.ToString());      
      return response.ToString();
    }
  }
}

The scenario I described will not affect your keypad or remote controls UNLESS you are already using the NO trigger input on the gate controller for either the remote or the keypad already. Your gate controller may have more than one input on it. If it does, please use one of the unused inputs.
If the controller has only one trigger input and it is being used, you may need to use some diodes when installing the RM10. It may be that the other trigger devices (Keypad and remote) wont care that there is a short on their outputs or it may be that they will malfunction. You may have to call their manufactures and ask if a direct short on the output will harm of make their products malfunction. I would probably put diodes on anyway.

I should have asked earlier. What is the model of the gate controller?[/quote]

Thanks for your help, though the above is a bit like greek to me :)! I’m pretty new to this, so may be in a bit over my head, but would love to try to get it working. The controller model says Liftmaster professional J19 on the board inside. If I take some pictures of the board, would you be able to walk me through the process? Happy to compensate you for your time–my spouse is about ready to kill me with all of the light switches, etc… I’ve been futzing with and if I break the gate operator I’m going to be in serious trouble!

Edited to add that while the controller says J19 inside, it’s the controller for the LA400 gate–manual here:
http://www.liftmaster.com/CatalogResourcesV3/en-us/shared/files/tucmanuals/0119244.pdf

Hi macrho, thanks for sharing the .Net code!

I tried it but I was not able to execute all functions. I was able to get the security token and all that so definitely seeing good signs, but I was not able to get accurate status and/or open close door. And my question is:

string strDeviceId = getDeviceId(strToken,“Garage Door Opener Left”);

Where is the “Garage Door Opener Left” defined? You think all GDO will be named like that, or I need to figure out myself by putting stop points in the loop and see what is my own GDO name?

Thanks for your time!

I had defined “Garage Door Opener Left” during my setup of the myQ application
You can use getInfo ( I think that’s right ) and inspect the return collection, a portion has your garage door openers. My other one was named “Garage Door Opener Right” – I’m not that unique!

If I knew enough about LUUP (I’m a hack at .net) a plugin should be relatively straight forward
Anyone want to mentor me or point me where to look?

[quote=“jeff3lo, post:53, topic:170458”]Hi macrho, thanks for sharing the .Net code!

I tried it but I was not able to execute all functions. I was able to get the security token and all that so definitely seeing good signs, but I was not able to get accurate status and/or open close door. And my question is:

string strDeviceId = getDeviceId(strToken,“Garage Door Opener Left”);

Where is the “Garage Door Opener Left” defined? You think all GDO will be named like that, or I need to figure out myself by putting stop points in the loop and see what is my own GDO name?

Thanks for your time![/quote]

There are a bunch of plugins on http://code.mios.com that have the key elements that you’d likely want to implement.

The sources for each are published, so folks building new plugins from these components tend to just credit the authors.

There are likely a few pieces that you’ll ultimately want:
a) A “parent” device that owns the implementation file (I_ChamberlainOpener1.xml, or whatever)
This will handle the creation of any necessary child-devices, along with handling any user-interaction with those children.

b) Per door, two children, one MotionSensor child device, and one SwitchPower device.
Technically you could do it all with the SwitchPower, but it’d be handy to have both. The MotionSensor would just use the standard/built-in definition (D_DoorSensor1.xml) when being created by the Parent. Similar for the LightSwitch, unless you want/need a fancier UI… and using the default impls will get you some immediate access to the Control Points (like AutHomation, SQRemote, etc)
These children need to be created by you using [tt]luup.chdev.{start|append|sync}[/tt] calls, which are typically made during [tt][/tt] in the implementation file.

c) [tt][/tt] handlers, in the implementation file, for turning the switch on/off, that translate into calls to the remote service.

d) A Timer-based luup ([tt]luup.call_timer[/tt]) to periodically poll the service, and update the state of various bits (such as the Vera switch, and SecuritySensor/door child devices, for each “door” in your decoded state)

e) Configuration for how frequently to poll (etc), done as a set of state variables in a custom serviceId

f) Some sort of UI, especially for the configuration components.

But best to start small, and work your way up. A basic set of D_.xml, I_.xml files will get you going with no UI, then you can incrementally add to that using the sample code on http://code.mios.com

As you progress, there are usually folks here that chime in with help on any specific questions you have (etc).

Thanks very much for the info guessed, I’m a tad intimidated but what the heck, I’ll give it a shot.
Is there any test environment that one can work in or do I have to work on my own vera?

Start small, kinda HelloWolrd (via luup.log calls) small, and incrementally add/test on Vera.

If it gets large/complex you can always use a tool, and for that there is a 3rd party IDE:
http://forum.micasaverde.com/index.php/topic,17780.0.html

There is an outline/walk through of how to build a plugin (for Somfy Blinds) on http://wiki.micasaverde.com

The most common mistake is file format, since you put your initial code into XML files and UI definitions into JSON files, and it’s easy to mess these up… So always validate them in an external tool/site (for raw XML/JSON formatting, not for a specific DTD)

But again, start simple and incrementally add/test and you’ll get there. My workflow involves editing on a Mac, and using SHell scripts (and SSH with keys, thanks to futzle) to push the files over to Vera and force it to reload/restart… That’s after the initial device has been manually created in Vera.

Thanks macrho.

I changed the GDO name to my own name, and your .Net code works like a charm! Can’t wait to see it becoming a luup plug-in one day.

The scenario I described will not affect your keypad or remote controls UNLESS you are already using the NO trigger input on the gate controller for either the remote or the keypad already. Your gate controller may have more than one input on it. If it does, please use one of the unused inputs.
If the controller has only one trigger input and it is being used, you may need to use some diodes when installing the RM10. It may be that the other trigger devices (Keypad and remote) wont care that there is a short on their outputs or it may be that they will malfunction. You may have to call their manufactures and ask if a direct short on the output will harm of make their products malfunction. I would probably put diodes on anyway.

I should have asked earlier. What is the model of the gate controller?[/quote]

Thanks for your help, though the above is a bit like greek to me :)! I’m pretty new to this, so may be in a bit over my head, but would love to try to get it working. The controller model says Liftmaster professional J19 on the board inside. If I take some pictures of the board, would you be able to walk me through the process? Happy to compensate you for your time–my spouse is about ready to kill me with all of the light switches, etc… I’ve been futzing with and if I break the gate operator I’m going to be in serious trouble!

Edited to add that while the controller says J19 inside, it’s the controller for the LA400 gate–manual here:
http://www.liftmaster.com/CatalogResourcesV3/en-us/shared/files/tucmanuals/0119244.pdf[/quote]

TB001 on page 37 of the manual you supplied shows the loop input you can use.
If there is no other triggering device on this input you are golden. If you do have another trigger on this input, read below.

Fist you need to make sure all of the safety devices are on your gate. Here is my disclaimer.
WARNING: Do not install automation equipment on any motorized door or gate unless you have the latest safety equipment supplied by it’s manufacture installed on it, including but not limited to, occupancy sensors, status sensors, reverse sensors and reverse mechanisms.
Use of these parts in controlling an motorized door or gate can be dangerous. Be aware, you are giving control of your electric door or gate motor and door or gate to an electrical device which can trigger your door or gate at any time.
007 Systems takes no responsibility for any damage or injury resulting in the use of these parts.

Here are the installation instructions.

  1. Attach the RM10’s wires to the NO Interrupt Loop input as shown on page 37. The common and the Normally Open Interrupt Loop inputs. Polarity does not matter.
  2. Plug the RM10’s power supply into the appliance module.
  3. Install a Z-Wave gate sensor to your gate. If you do not have one, we sell those also.
  4. Include the RM-10’s appliance module into your Vera.
  5. Include the gate sensor into your Vera.
  6. if everything is working secure all of the wires and make sure the appliance module is protected from moisture.

If you have other triggers on this input you will have to use diodes to keep the short from shorting the other trigger. If this is the case, contact me.
If your gate controller is too far away and you are not getting signal out at the gate, you will have to run wires into the home and install the appliance module, RM10 and gate sensor in a location closer to the vera.

Contact me if you have any questions.
Good luck.

I think it might be helpful to split the hardware hacks and actual plugin discussion.