domotz-remote-pawn
Version:
Domotz Agent
117 lines (107 loc) • 4.53 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 myConsole = resourceLocator.log.decorateLogs();
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) {
myConsole.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;
myConsole.info(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) {
myConsole.error(subscription.correlation_id + ' -Cannot send UPnp event notification to engine: ' + error);
}
if (response.statusCode !== 204) {
myConsole.error(subscription.correlation_id + ' - Unexpected status code:' + response.statusCode);
}
}
);
} else {
myConsole.info(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;