domotz-remote-pawn
Version:
Domotz Agent
122 lines (107 loc) • 4.59 kB
JavaScript
/** This file is part of Domotz Agent.
* Copyright (C) 2016 Domotz Ltd
*
* Domotz Agent is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Domotz Agent is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>.
**/
/**
* Created by Massimiliano Cuzzoli <mcuzzoli@domotz.com> on 21/04/15.
*
*/
var handleUpnpEvent = function (request, response, resourceLocator) {
var body = '';
var xml2js = resourceLocator.xml2js;
var processors = resourceLocator.xml2jsProcessor;
var credentials = resourceLocator.configuration.credentials;
var engineEndpoint = resourceLocator.configuration.engine.api_endpoints.hub;
function extractFirstValidProperty(jsonBody, subscription) {
var propertyElement = jsonBody.propertyset.property[0];
var property;
var propertyValue;
for (var i in propertyElement) {
if (propertyElement.hasOwnProperty(i) && i[0] !== '$') {
// Skip attributes and namespace declarations
if (subscription.properties.indexOf(i) >= 0) {
property = i;
propertyValue = propertyElement[i][0]._;
break;
}
}
}
if (property) {
return {name: property, value: propertyValue};
}
else {
return null;
}
}
var handleOnEnd = function () {
var parser = new xml2js.Parser({
xmlns: true,
tagNameProcessors: [processors.stripPrefix]
});
parser.parseString(body,
function (error, jsonBody) {
if (error) {
console.warn("Error in XML:" + body + " - " +
JSON.stringify(error));
response.writeHead(400);
response.end();
return;
}
var subscription = resourceLocator.upnp.registry.getSubscriptionById(request.headers.sid);
var property = extractFirstValidProperty(jsonBody, subscription);
if (property) {
var sentBody = {
'payload': property,
'meta_info': {
'address': subscription.device_info[0],
'port': subscription.device_info[1],
'protocol': 'UPNP',
'event': request.headers.nts
}
};
var actualUrl = engineEndpoint + subscription.callback_url;
console.log(subscription.correlation_id + " - Signaling property `" + property.name + "` change to " + actualUrl);
resourceLocator.request({
method: 'POST',
uri: actualUrl,
headers: {'Content-Type': 'application/json'},
json: true,
body: sentBody,
auth: {
user: credentials.user,
password: credentials.password
}
}, function (error, response) {
if (error) {
console.error(subscription.correlation_id + " -Cannot send UPnp event notification to engine: " + error);
}
if (response.statusCode !== 204) {
console.error(subscription.correlation_id + " - Unexpected status code:" + response.statusCode);
}
});
}
else {
console.log(subscription.correlation_id + " - No interesting property found");
}
response.writeHead(200);
response.end();
});
};
request.on('data', function (data) {
body += data;
});
request.on('end', handleOnEnd);
};
module.exports.handleUpnpEvent = handleUpnpEvent;