josefkyrian

OCPP server

Mar 30th, 2024 (edited)
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //! README
  2.  
  3. // set charging limit
  4. // curl 'http://HOST:3030/limit?amps=10.4&numberPhases=3'
  5.  
  6. // stop charging
  7. // curl 'http://HOST:3030/stop'
  8.  
  9. // start charging
  10. // curl 'http://HOST:3030/start?amps=10&numberPhases=3'
  11.  
  12.  
  13. const express = require('express');
  14. const WebSocket = require('ws');
  15. const http = require('http');
  16.  
  17. const app = express();
  18. const server = http.createServer(app);
  19.  
  20. const wss = new WebSocket.Server({ server });
  21.  
  22. const clients = [];
  23.  
  24. wss.on('connection', (ws) => {
  25.     console.log('Client connected via WebSocket');
  26.     clients.push(ws);
  27.     ws.on('close', (code, reason) => {
  28.         console.log(`Connection closed. Code: ${code}, Reason: ${reason}`);
  29.         const i = clients.indexOf(ws);
  30.         if (i !== -1) {
  31.             clients.splice(i, 1);
  32.         }
  33.     });
  34.  
  35.  
  36.     ws.on('message', (message) => {
  37.         console.log('>> Got:', JSON.stringify(JSON.parse(message.toString()), null));
  38.         handleMessage(ws, message);
  39.     });
  40. });
  41.  
  42. function handleMessage(ws, message) {
  43.     let parsedMessage;
  44.  
  45.     try {
  46.         parsedMessage = JSON.parse(message);
  47.     } catch (error) {
  48.         console.error('Error parsing message', message);
  49.         return;
  50.     }
  51.  
  52.     const response = replyMessage(parsedMessage);
  53.     if (response) {
  54.         console.log('<< Reply:', JSON.stringify(response, null));
  55.         ws.send(JSON.stringify(response));
  56.     }
  57.     console.log('-----------------------')
  58. }
  59.  
  60. function replyMessage(message){
  61.     const [messageTypeId, uniqueId, action, payload] = message;
  62.     var replyCounter = 0;
  63.     //initiated by Charging Station
  64.     if (uniqueId.startsWith("xxx")) {
  65.         // got reply not request
  66.         return;
  67.     }else if (action === "BootNotification") {
  68.         return [3, uniqueId, { "status": "Accepted", "currentTime": new Date().toISOString(), "interval": 10 }]; //fixed Heartbeat Interval
  69.  
  70.     }else if (action === "StartTransaction") {
  71.         return [3, uniqueId, {
  72.             "transactionId": 123,
  73.             "idTagInfo": {
  74.                 "status": "Accepted",
  75.             },
  76.         }];
  77.  
  78.     }else if (action === "StopTransaction") {
  79.         return [3, uniqueId, {
  80.             "idTagInfo": {
  81.                 "status": "Accepted",
  82.             },
  83.         }];
  84.        
  85.     }else if(action === "Heartbeat") {
  86.         return [3, uniqueId, { "currentTime": new Date().toISOString() }];
  87.  
  88.     }else if(action === "StatusNotification"){
  89.         return [3, uniqueId, {}];
  90.  
  91.     }else if(action === "MeterValues"){
  92.         return [3, uniqueId, {}];
  93.  
  94.     }else if(action === "Authorize"){
  95.         // Check if ID in Backend in the future, or similar
  96.         return [3, uniqueId, { idTagInfo: { "status": "Accepted" } }];
  97.    
  98.     // Initiated by FrontEnd
  99.     // -- Reset
  100.     }else if(action === "Reset"){
  101.         // Check if ID in Backend in the future, or similar
  102.         replyCounter = replyCounter+1;
  103.         return [2, replyCounter.toString(), "Reset", { type: "Hard" }];
  104.    
  105.     // -- Remote Start Transaction
  106.     // }else if(action === "RemoteStartTransactionRequest"){
  107.     //  // Check if ID in Backend in the future, or similar
  108.     //  replyCounter = replyCounter+1;
  109.     //  return [2, replyCounter.toString(), "RemoteStartTransactionRequest",{"idTag":"6ac32b40","connectorId":1}];
  110.     // // -- Remote Stop Transaction
  111.     // }else if(action === "RemoteStopTransactionRequest"){
  112.     //  // Check if ID in Backend in the future, or similar
  113.     //  replyCounter = replyCounter+1;
  114.     //  return [2, replyCounter.toString(), "RemoteStopTransactionRequest", { "transactionId": 1}];  
  115.        
  116.     }else{
  117.         console.log("Unknown MEssage!!!!");
  118.         console.log("*****");
  119.         console.log(message);
  120.         console.log("*****");
  121.     };
  122. }
  123.  
  124.  
  125. app.get('/', (req, res) => {
  126.     res.send('Hello from Express and WebSocket OCPP Server');
  127. });
  128. app.get('/limit', (req, res) => {
  129.     const currentLimit = +req.query.amps;
  130.     const numberPhases = +(req.query.numberPhases || 3);
  131.     if (clients.length) {
  132.         const message = [2, `xxx${Date.now()}`, "SetChargingProfile", {
  133.             "connectorId": 1,
  134.             "csChargingProfiles": {
  135.                 "chargingProfileId": 1,
  136.                 "transactionId": 123,
  137.                 "stackLevel": 0,
  138.                 "chargingProfilePurpose": "ChargePointMaxProfile",
  139.                 "chargingProfileKind": "Absolute",
  140.                 "chargingSchedule": {
  141.                     "chargingRateUnit": "A",
  142.                     "chargingSchedulePeriod": [
  143.                         {
  144.                             "startPeriod": 0,
  145.                             "limit": currentLimit,
  146.                             "numberPhases": numberPhases,
  147.                         }
  148.                     ]
  149.                 }
  150.             }
  151.         }];
  152.         for (const ws of clients) {
  153.             ws.send(JSON.stringify(message));
  154.         }
  155.         console.log('<< Send:', JSON.stringify(message, null));
  156.         res.send(`Message sent\n${JSON.stringify(message, null, 2)}`);
  157.     }else {
  158.         res.status(400).send('No connected client');
  159.     }
  160. });
  161. app.get('/stop', (req, res) => {
  162.     if (clients.length) {
  163.         const message = [2, `xxx${Date.now()}`, "RemoteStopTransaction", {
  164.             "transactionId": 123,
  165.         }];
  166.         for (const ws of clients) {
  167.             ws.send(JSON.stringify(message));
  168.         }
  169.         console.log('<< Send:', JSON.stringify(message, null));
  170.         res.send(`Message sent\n${JSON.stringify(message, null, 2)}`);
  171.     }else {
  172.         res.status(400).send('No connected client');
  173.     }
  174. });
  175. app.get('/start', (req, res) => {
  176.     const currentLimit = +(req.query.amps || 10);
  177.     const numberPhases = +(req.query.numberPhases || 3);
  178.     if (clients.length) {
  179.         const message = [2, `xxx${Date.now()}`, "RemoteStartTransaction", {
  180.             "connectorId": 1,
  181.             "idTag": "SomeIdTaggggg",
  182.             "chargingProfile": {
  183.                 "chargingProfileId": 1,
  184.                 "transactionId": 123,
  185.                 "stackLevel": 0,
  186.                 "chargingProfilePurpose": "ChargePointMaxProfile",
  187.                 "chargingProfileKind": "Absolute",
  188.                 "chargingSchedule": {
  189.                     "chargingRateUnit": "A",
  190.                     "chargingSchedulePeriod": [
  191.                         {
  192.                             "startPeriod": 0,
  193.                             "limit": currentLimit,
  194.                             "numberPhases": numberPhases,
  195.                         }
  196.                     ]
  197.                 }
  198.             },
  199.         }];
  200.         for (const ws of clients) {
  201.             ws.send(JSON.stringify(message));
  202.         }
  203.         console.log('<< Send:', JSON.stringify(message, null));
  204.         res.send(`Message sent\n${JSON.stringify(message, null, 2)}`);
  205.     }else {
  206.         res.status(400).send('No connected client');
  207.     }
  208. });
  209.  
  210. server.listen(3030, () => {
  211.     console.log('HTTP and WebSocket server is running on http://localhost:3030');
  212. });
  213.  
Add Comment
Please, Sign In to add comment