@spenwall/myq-api
v2.0.3
Published
An updated API to interface with myQ devices
Downloads
5
Maintainers
Readme
myq-api
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
- new MyQ()
- login(email, password)
- getDevices()
- getDevice(serialNumber)
- getDoorState(serialNumber)
- getLightState(serialNumber)
- setDoorState(serialNumber, action)
- setLightState(serialNumber, action)
- _getAccountId()
- _getDeviceState(serialNumber, _stateAttribute)
- _setDeviceState(serialNumber, _action, _stateAttribute)
- _executeServiceRequest(_config)
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.