Skip to content

HTTP

D.device.http exposes verb-specific methods for talking to the device over HTTP or HTTPS. Everything routes through the collector, so the driver only ever reaches the managed device — not the open internet.

D.device.http.get({ url: '/api/status' }, function (error, response, body) {
if (error) return D.failure(D.errorType.RESOURCE_UNAVAILABLE);
if (response.statusCode !== 200) return D.failure(D.errorType.GENERIC_ERROR);
var data = JSON.parse(body);
// ... turn data into variables
});

Every callback is (error, response, body) — same shape across get, post, put, delete.

D.device.http.get({
url: '/api/metrics', // path on the device; absolute or relative
username: 'custom', // overrides D.device.username() for this call
password: 'secret', // overrides D.device.password() for this call
port: 8443, // override port (defaults to 80/443)
protocol: 'https', // 'http' or 'https'
rejectUnauthorized: false, // accept self-signed certs (device reality check)
headers: { // custom headers
'accept': 'application/json',
'x-auth-token': '...'
},
body: '...', // for post/put — request body
jar: true, // follow cookies across calls
timeout: 5000, // ms
auth: { bearer: 'xxx' } // or { digest: true } for digest auth
}, callback);

If username / password are not set on the options object, the call uses the Custom Driver Management credentials configured in the Domotz portal (same ones D.device.username() / D.device.password() return).

Set username and password in options, or leave them out to use the portal-configured CDM credentials.

D.device.http.get({
url: '/api/v2/devices',
auth: { bearer: 'eyJhbGci...' }
}, callback);
D.device.http.get({
url: '/api/stats',
auth: { digest: true, username: 'u', password: 'p' }
}, callback);

Just set the header explicitly:

D.device.http.get({
url: '/api/foo',
headers: { 'x-api-key': 'xxx' }
}, callback);

Many devices ship with self-signed HTTPS certificates. Pass rejectUnauthorized: false to accept them:

D.device.http.get({
url: '/api/info',
protocol: 'https',
port: 443,
rejectUnauthorized: false
}, callback);

To verify the cert explicitly instead, use D.device.http.getTLSCertificate to fetch and inspect it before the main call.

function get_status() {
D.device.http.get({ url: '/api/metrics' }, function (error, response, body) {
if (error) {
console.error('HTTP error', error);
return D.failure(D.errorType.RESOURCE_UNAVAILABLE);
}
if (response.statusCode === 401 || response.statusCode === 403) {
return D.failure(D.errorType.AUTHENTICATION_ERROR);
}
if (response.statusCode >= 500) {
return D.failure(D.errorType.RESOURCE_UNAVAILABLE);
}
if (response.statusCode !== 200) {
console.error('Unexpected status', response.statusCode, body);
return D.failure(D.errorType.GENERIC_ERROR);
}
try {
var data = JSON.parse(body);
publish(data);
} catch (e) {
return D.failure(D.errorType.PARSING_ERROR);
}
});
}

The body argument is always a string. Call JSON.parse(body) yourself — don’t ask the library to parse. That way a malformed response becomes a catchable error in your handler, not a silent corruption.

Most devices that paginate expose a cursor or a ?page=N query param. Recurse with a counter until the response is empty or the cursor is null:

function fetchAll(page, acc, done) {
D.device.http.get({ url: '/api/items?page=' + page }, function (err, res, body) {
if (err || res.statusCode !== 200) return done(err || new Error('status ' + res.statusCode));
var data = JSON.parse(body);
acc = acc.concat(data.items || []);
if (data.has_next) return fetchAll(page + 1, acc, done);
done(null, acc);
});
}
function get_status() {
fetchAll(1, [], function (err, items) {
if (err) return D.failure(D.errorType.RESOURCE_UNAVAILABLE);
// turn items into a table
});
}