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 🙏

© 2024 – Pkg Stats / Ryan Hefner

myq-api

v2.0.4

Published

An updated API to interface with myQ devices

Downloads

26

Readme

myq-api

node-current npm GitHub Workflow Status (branch) Coveralls GitHub Stryker mutation score GitHub

Interface with your myQ devices using this npm module. Works with both Chamberlain and LiftMaster.

Supports:

  • Opening or closing a door.
  • Checking whether a door is open or closed.
  • Turning on or turning off a light.
  • Checking whether a light is turned on or turned off.
  • Getting the metadata and state of all devices on an account.
  • Getting the metadata and state of a specific device.
  • A few other advanced usages documented below.

Installation

npm install myq-api

Examples

See example.js and example_async.js for end-to-end examples of using this module. Configure EMAIL and PASSWORD in these examples to enable running them against your own myQ account!

API

Usage

new MyQ()

Initialize the MyQ API.

This used to take in an email and password, but these parameters have been deprecated in favor of login(username, password).

const MyQ = require('myq-api');

const account = new MyQ();

login(email, password)

Log into a myQ account and fetch a security token.

This must be called before the rest of this API is called. This used to take in no parameters, but the interface has been updated to take in the account email and password.

Note that the security token is short-lived and will not work after some time, so this might have to be called again to retrieve a new security token.

| Parameter | Required | Type | Details | |-----------|----------|--------|------------------------------| | email | yes | string | Email for the myQ account | | password | yes | string | Password for the myQ account |

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function login() {
  try {
    const account = new MyQ();
    const result = await account.login(email, password)
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK",
  "securityToken": <securityToken>
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if arguments are not sufficiently validated beforehand)
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • AUTHENTICATION_FAILED
  • AUTHENTICATION_FAILED_ONE_TRY_LEFT
  • AUTHENTICATION_FAILED_LOCKED_OUT

getDevices()

Get the metadata and state of all devices on the myQ account.

login() must be called before this.

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account.getDevices())
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });
}

async/await example:

const MyQ = require('myq-api');

async function getDevices() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account.getDevices();
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK",
  "devices": [device1, device2, ...]
}

For robust error handling, catch and handle the following errors:

  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE

getDevice(serialNumber)

Get the metadata and state of a specific device on the myQ account.

login() must be called before this.

| Parameter | Required | Type | Details | |--------------|----------|---------|-------------------------| | serialNumber | yes | string | Serial number of device |

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account.getDevice(serialNumber)
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function getDevice() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account.getDevice(serialNumber);
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK",
  "device": <device>
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if argument is not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • DEVICE_NOT_FOUND

getDoorState(serialNumber)

Check whether a door on the myQ account is open or closed.

login() must be called before this.

Note that this can report back intermediary states between open and closed as well.

| Parameter | Required | Type | Details | |--------------|----------|---------|-----------------------| | serialNumber | yes | string | Serial number of door |

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account.getDoorState(serialNumber)
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function getDoorState() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account.getDoorState(serialNumber);
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK",
  "deviceState": <deviceState>
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if argument is not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • DEVICE_NOT_FOUND
  • INVALID_DEVICE

getLightState(serialNumber)

Check whether a light on the myQ account is turned on or turned off.

login() must be called before this.

| Parameter | Required | Type | Details | |--------------|----------|---------|------------------------| | serialNumber | yes | string | Serial number of light |

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account.getLightState(serialNumber)
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function getLightState() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account.getLightState(serialNumber);
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK"
  "deviceState": <deviceState>
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if argument is not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • DEVICE_NOT_FOUND
  • INVALID_DEVICE

setDoorState(serialNumber, action)

Open or close a door on the myQ account.

login() must be called before this.

| Parameter | Required | Type | Details | |--------------|----------|--------|----------------------------------------------------------------------------------------| | serialNumber | yes | string | Serial number of door | | action | yes | symbol | Action to request on door (either MyQ.actions.door.OPEN or MyQ.actions.door.CLOSE) |

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account.setDoorState(serialNumber, MyQ.actions.door.OPEN)
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function setDoorState() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account.setDoorState(serialNumber, MyQ.actions.door.OPEN);
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK"
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if arguments are not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • DEVICE_NOT_FOUND
  • INVALID_DEVICE

setLightState(serialNumber, action)

Turn on or turn off a light on the myQ account.

login() must be called before this.

| Parameter | Required | Type | Details | |--------------|----------|--------|-------------------------------------------------------------------------------------------------| | serialNumber | yes | string | Serial number of light | | action | yes | symbol | Action to request on light (either MyQ.actions.light.TURN_ON or MyQ.actions.light.TURN_OFF) |

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account.setLightState(serialNumber, MyQ.actions.light.TURN_ON)
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function setLightState() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account.setLightState(serialNumber, MyQ.actions.light.TURN_ON);
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK"
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if arguments are not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • DEVICE_NOT_FOUND
  • INVALID_DEVICE

_getAccountId()

Get the account ID of the myQ account.

This is meant for internal use, but this is exposed in case one wants to fetch the account ID. login() must be called before this.

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account._getAccountId()
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function getAccountId() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account._getAccountId();
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK",
  "accountId": <accountId>
}

For robust error handling, catch and handle the following errors:

  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE

_getDeviceState(serialNumber, _stateAttribute)

Get the value of a state attribute for a device on the myQ account.

This is meant for internal use, but this is exposed in case one wants to fetch artibrary state attributes for a device. login() must be called before this.

| Parameter | Required | Type | Details | |-----------------|----------|--------|-----------------------------------| | serialNumber | yes | string | Serial number of device | | _stateAttribute | yes | string | State attribute to fetch value of |

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account._getDeviceState(serialNumber, 'door_state')
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function getDeviceState() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account._getDeviceState(serialNumber, 'door_state');
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK",
  "deviceState": <deviceState>
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if arguments are not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • DEVICE_NOT_FOUND
  • DEVICE_STATE_NOT_FOUND

_setDeviceState(serialNumber, _action, _stateAttribute)

Initiate an action for a device on the myQ account.

This is meant for internal use, but this is exposed in case one wants to initiate arbitrary actions for a device (e.g. for a device without first-class support in this API). login() must be called before this.

The _stateAttribute parameter would not be needed here normally. Since a 500 error is returned from the service when a state update is not supported on a device, however, we check that the state attribute we want to update is present on the device before we attempt a state update.

| Parameter | Required | Type | Details | |-----------------|----------|--------|--------------------------------------------------| | serialNumber | yes | string | Serial number of device | | _action | yes | string | Action to request on device | | _stateAttribute | yes | string | State attribute to ensure presence of beforehand |

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account._setDeviceState(serialNumber, 'open', 'door_state')
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function setDeviceState() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account._setDeviceState(serialNumber, 'open', 'door_state');
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful:

{
  "code": "OK"
}

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if arguments are not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • DEVICE_NOT_FOUND
  • DEVICE_STATE_NOT_FOUND

_executeServiceRequest(_config)

Execute a myQ service request.

This is meant for internal use, but this is exposed in case one wants to send arbitrary requests to the myQ service.

Default values for header fields are used if they are not explicitly specified. Specify null for such fields in order to avoid sending them as part of the request. In particular, the SecurityToken field is set to the cached security token by default if it is not explicitly specified. If the SecurityToken field is not specified and the security token is not cached, an error is thrown. Specify a null SecurityToken in order to avoid sending it as part of the request and prevent the error from being thrown.

| Parameter | Required | Type | Details | |-----------|----------|--------|---------------------------------------------------------------| | _config | yes | object | axios config |

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password)
  .then(function(result) {
    return account._executeServiceRequest({
      baseURL: constants._baseUrls.auth,
      url: constants._routes.login,
      method: 'post',
      headers: {
        SecurityToken: null,
      },
      data: {
        Username: email,
        Password: password,
      },
    })
  }).then(function (result) {
    console.log(result);
  }).catch(function (error) {
    console.error(error);
  });

async/await example:

const MyQ = require('myq-api');

async function executeServiceRequest() {
  try {
    const account = new MyQ();
    await account.login(email, password);
    const result = await account._executeServiceRequest({
      baseURL: constants._baseUrls.auth,
      url: constants._routes.login,
      method: 'post',
      headers: {
        SecurityToken: null,
      },
      data: {
        Username: email,
        Password: password,
      },
    });
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Returned object if call is successful: axios response.

For robust error handling, catch and handle the following errors:

  • INVALID_ARGUMENT (if argument is not sufficiently validated beforehand)
  • LOGIN_REQUIRED
  • SERVICE_REQUEST_FAILED
  • SERVICE_UNREACHABLE
  • INVALID_SERVICE_RESPONSE
  • AUTHENTICATION_FAILED
  • AUTHENTICATION_FAILED_ONE_TRY_LEFT
  • AUTHENTICATION_FAILED_LOCKED_OUT
  • DEVICE_NOT_FOUND

Error handling

An error returned from the API will include a code as well as an error message if applicable.

| Possible error codes | Explanation |----------------------------------------------|-----------------------------------------------------------------------------------| | ERR_MYQ_INVALID_ARGUMENT | Argument is unspecified or invalid. | | ERR_MYQ_LOGIN_REQUIRED | login() has not been called yet or security token has expired. | | ERR_MYQ_AUTHENTICATION_FAILED | Authentication attempt failed. | | ERR_MYQ_AUTHENTICATION_FAILED_ONE_TRY_LEFT | Authentication attempt failed, one try left before user is locked out. | | ERR_MYQ_AUTHENTICATION_FAILED_LOCKED_OUT | Authentication attempt failed, account is locked out. Password needs to be reset. | | ERR_MYQ_DEVICE_NOT_FOUND | Specified device not found. | | ERR_MYQ_DEVICE_STATE_NOT_FOUND | Specified state attribute not found on device. | | ERR_MYQ_INVALID_DEVICE | Action cannot be done on device. | | ERR_MYQ_SERVICE_REQUEST_FAILED | Service request could not be set up or sent. | | ERR_MYQ_SERVICE_UNREACHABLE | Service cannot be reached at this time. | | ERR_MYQ_INVALID_SERVICE_RESPONSE | Invalid response received from service. |

Returned object if a call is unsuccessful:

{
  code: <errorCode>,
  message: <errorMessage>
}

Since the underlying myQ API is volatile, there might be changes unforeseen by the current version of this software. If you encounter an unexpected error, please create a GitHub issue.

NOTE: It is recommended that error codes are checked against the provided constants (MyQ.constants.codes) instead of hardcoded raw strings.

Example:

const MyQ = require('myq-api');

const account = new MyQ();
account.login(email, password) // assuming parameters are valid here, otherwise INVALID_ARGUMENT can be thrown as well
  .then(function (result) {
    console.log(result);
  }).catch(function (error) {
    if (error.code === MyQ.constants.codes.SERVICE_REQUEST_FAILED) {
      // handle client-side errors when setting up service request
    } else if ([MyQ.constants.codes.SERVICE_UNREACHABLE, MyQ.constants.codes.INVALID_SERVICE_RESPONSE].contains(error.code)) {
      // handle service errors
    } else if (error.code === MyQ.constants.codes.AUTHENTICATION_FAILED) {
      // handle failed authentication
    } else if (error.code === MyQ.constants.codes.AUTHENTICATION_FAILED_ONE_TRY_LEFT) {
      // handle failed authentication, one try left
    } else if (error.code === MyQ.constants.codes.AUTHENTICATION_FAILED_LOCKED_OUT) {
      // handle failed authentication, user locked out
    }
  });

async/await example:

const MyQ = require('myq-api');

async function login() {
  try {
    const account = new MyQ();
    const result = await account.login(email, password); // assuming parameters are valid here, otherwise INVALID_ARGUMENT can be thrown as well
    console.log(result);
  } catch (error) {
    if (error.code === MyQ.constants.codes.SERVICE_REQUEST_FAILED) {
      // handle client-side errors when setting up service request
    } else if ([MyQ.constants.codes.SERVICE_UNREACHABLE, MyQ.constants.codes.INVALID_SERVICE_RESPONSE].contains(error.code)) {
      // handle service errors
    } else if (error.code === MyQ.constants.codes.AUTHENTICATION_FAILED) {
      // handle failed authentication
    } else if (error.code === MyQ.constants.codes.AUTHENTICATION_FAILED_ONE_TRY_LEFT) {
      // handle failed authentication, one try left
    } else if (error.code === MyQ.constants.codes.AUTHENTICATION_FAILED_LOCKED_OUT) {
      // handle failed authentication, user locked out
    }
  }
}

Debugging

The debug module has been integrated to log service calls via axios-debug-log. Simply set the DEBUG environment variable to myq-api to get detailed logs of service requests, responses, and errors. This is especially helpful if you are running into unexpected errors and want to dig deeper.

License

MIT