UNPKG

node-red-contrib-ocpp

Version:

A set of nodes to communicate via OCPP to a compatible charge box or central system

123 lines (94 loc) 3.8 kB
'use strict'; const path = require('path'); const soap = require('soap'); const Logger = require('./utils/logdata'); const debug = require('debug')('anl:ocpp:cp-req-soap'); module.exports = function(RED) { function OcppRequestCPNode(config) { RED.nodes.createNode(this, config); debug('Starting cp-req-soap node'); var node = this; this.remotecs = RED.nodes.getNode(config.remotecs); this.url = this.remotecs.url; // this.cbId = this.remotecs.cbId; this.cbId = config.name; this.ocppVer = config.ocppver; this.name = config.name || this.remotecs.name; this.command = config.command; this.cmddata = config.cmddata; this.logging = config.log; this.pathlog = config.pathlog; const logger = new Logger(this, this.pathlog, this.name); logger.enabled = (this.logging && (typeof this.pathlog === 'string') && this.pathlog !== ''); this.on('input', function(msg) { // set up soap requests for SOAP 1.2 headers var wsdlOptions = { forceSoap12Headers: true, }; // create the client let wsdlFile = (node.ocppVer == '1.5s') ? 'ocpp_centralsystemservice_1.5_final.wsdl' : 'OCPP_CentralSystemService_1.6.wsdl'; soap.createClient(path.join(__dirname, wsdlFile), wsdlOptions, function(err, client){ if (err) node.error(err); else { var cbId = node.cbId; msg.ocpp = {}; msg.ocpp.command = msg.payload.command || node.command; msg.ocpp.chargeBoxIdentity = cbId; msg.ocpp.url = node.url; msg.ocpp.ocppVer = node.ocppVer; let cmddata; if (node.cmddata){ cmddata = JSON.parse(node.cmddata); } msg.ocpp.data = msg.payload.data || cmddata; if (!msg.ocpp.command){ node.error('Missing Command in SOAP request message'); debug('Missing Command in SOAP request message'); return; } else if (!msg.ocpp.data){ node.error('Missing Data in SOAP request message'); debug('Missing Data in SOAP request message'); return; } // set up or target Central System client.setEndpoint(msg.ocpp.url); // add headers that are specific to OCPP specification let addressing = 'http://www.w3.org/2005/08/addressing'; client.addSoapHeader({'tns:chargeBoxIdentity': msg.ocpp.chargeBoxIdentity}); client.addSoapHeader({To: msg.ocpp.url}, null, null, addressing); if (node.ocppVer != '1.5s'){ let act = '<Action xmlns="' + addressing + '" soap:mustUnderstand="true">' + msg.ocpp.command + '</Action>'; client.addSoapHeader(act); } if (node.pathlog == '') node.logging = false; if (node.logging){ client.on('request', function(xmlSoap){ logger.log('request', xmlSoap); }); client.on('response', function(xmlSoap){ logger.log('replied', xmlSoap); }); client.on('soapError', function(err){ logger.log('error', err); }); } // send the specific OCPP message client[msg.ocpp.command](msg.ocpp.data, function(err, response){ if (err) { // report any errors node.error(err); msg.payload = err; node.send(msg); } else { // put the response to the request in the message payload and send it out the flow msg.payload.data = response; node.send(msg); } }); } }); }); } // register our node RED.nodes.registerType('CP Request SOAP', OcppRequestCPNode); };