Jump to content

OCPP 1.6 JSON and websockets

Hi,

I'm trying to build a backend system using OCPP 1.6 JSON over websockets in Node. I am having some trouble with the whole websockets thing, I have experience with REST api's but this is throwing me for a loop.

 

Essentially where I am at is that I receive a message from the charger like this: 

[2,
   "19223201",
   "BootNotification",
   {"chargePointVendor": "VendorX", "chargePointModel": "SingleSocketCharger"}
]

I need to put this in a database which I can probably figure out myself, but more importantly I need to de-construct the message and generate an appropriate response.

 

In this case it would look something like this: 

[3,
   "19223201",
   {"status":"Accepted", "currentTime":"2013-02-01T20:53:32.486Z", "heartbeatInterval":300}
]

 

And I have no idea how to do it. Essentially I need a lot of if statements like if the massage has "BootNotification" in it, then send the accept message and if it has something else, then respond appropriately.

 

If someone can help, I'll buy you a beer or coffee or beverage of your choosing? :D

 

Edit: the documentation for the OCPP protocol is available here: https://www.openchargealliance.org/downloads/

My PC CPU: 2600K@4.5GHz 1.3v Cooler: Noctua NH-U12P SE2 MB: ASUS Maximus IV RAM: Kingston 1600MHz 8GB & Corsair 1600MHz 16GB GPU: 780Ti Storage: Samsung 850 Evo 500GB SSD, Samsung 830 256GB SSD, Kingston 128GB SSD, WD Black 1TB,WD Green 1TB. PSU: Corsair AX850 Case: CM HAF X. Optical drive: LG Bluray burner  MacBook Pro, Hackintosh

Link to comment
Share on other sites

Link to post
Share on other sites

  • 2 years later...

Okay, what exactly is your problem here?

All messages have the same structure.

As you can see, it's a normal array.

Second item is the charger ID.

Instead of using many ifs, consider using switch on the third element (in documentation this field is called message title).

 

So it should look like this:

switch (message[2]) {
case 'BootNotification':
  ws.send( <deconstructed message> )
  break
case <other case>:
  <some stuff>
  break
}

deconstruction could look like this:

/*
Your message (in this code stored as `message` variable):
[2,
   "19223201",
   "BootNotification",
   {"chargePointVendor": "VendorX", "chargePointModel": "SingleSocketCharger"}
]
*/

toSend = [
  3,
  message[1],	// second field of received message - charger ID
  {
    'status': 'Accepted',
    'currentTime': new Date().toISOString(),
    // in the documentation they say that as it works on Sockets,
    // it would work with one heartbeat per day,
    // but let's keep that 300 just in case 
    'heartbeatInterval': 300
  }
]

I'm not 100% sure, because I haven't used that protocol yet, but according to the documentation it should work.

 

Additionally, you want to store connections in an object, but that's another matter.

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, Octoturge said:

Okay, what exactly is your problem here?

All messages have the same structure.

As you can see, it's a normal array.

Second item is the charger ID.

Instead of using many ifs, consider using switch on the third element (in documentation this field is called message title).

 

So it should look like this:

switch (message[2]) {
case 'BootNotification':
  ws.send( <deconstructed message> )
  break
case <other case>:
  <some stuff>
  break
}

deconstruction could look like this:

/*
Your message (in this code stored as `message` variable):
[2,
   "19223201",
   "BootNotification",
   {"chargePointVendor": "VendorX", "chargePointModel": "SingleSocketCharger"}
]
*/

toSend = [
  3,
  message[1],	// second field of received message - charger ID
  {
    'status': 'Accepted',
    'currentTime': new Date().toISOString(),
    // in the documentation they say that as it works on Sockets,
    // it would work with one heartbeat per day,
    // but let's keep that 300 just in case 
    'heartbeatInterval': 300
  }
]

I'm not 100% sure, because I haven't used that protocol yet, but according to the documentation it should work.

 

Additionally, you want to store connections in an object, but that's another matter.

I can't remember exactly, I think I might have solved this one. Not sure if I got multiple connections working by putting them in objects though. 

 

Do you work with OCPP?

 

My PC CPU: 2600K@4.5GHz 1.3v Cooler: Noctua NH-U12P SE2 MB: ASUS Maximus IV RAM: Kingston 1600MHz 8GB & Corsair 1600MHz 16GB GPU: 780Ti Storage: Samsung 850 Evo 500GB SSD, Samsung 830 256GB SSD, Kingston 128GB SSD, WD Black 1TB,WD Green 1TB. PSU: Corsair AX850 Case: CM HAF X. Optical drive: LG Bluray burner  MacBook Pro, Hackintosh

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, lufihengr said:

I can't remember exactly, I think I might have solved this one. Not sure if I got multiple connections working by putting them in objects though. 

 

Do you work with OCPP?

 

not yet

by not yet I mean I'll be working in a week or so haha 😆

Link to comment
Share on other sites

Link to post
Share on other sites

When working with WebSockets you need to design your application differently from conventional request/response systems (such as your previous experience with REST --- i.e. "representational state transfer")

 

WebSockets is designed so that it opens up a two-way communication between either side --- i.e. "sockets".

 

The best analogy I can think of is like having two neighbors throwing paper planes into each other's windows to pass a message to each other.

You may come home and find a bunch of paper planes on the floor (from your neighbor) in your room.

You can open these up in any order you want, no one cares...

If your protocol (agreement you made with each other) is that a red paper plane comes in, you open it first and you MUST send something back. <-- this is a standard --- like OCPP

 

This way your neighbor knows that if you don't respond to the red paper plane, you probably went on a vacation and he can take a break from trying to communicate with you.

 

A few things here to keep in mind.

(a) order received is never guaranteed... there are things like putting numbers to each message so you know what order you SHOULD read it in, but delivery isn't guaranteed to come in that order. Say I wrote a bunch of letters for a long message, and I got someone else to fold the paper plane and threw them across into your window, maybe they did something out of sequence, but who cares, since you should read the messages as numbered anyway.

 

(b) sometimes you might not receive it at all... windy conditions can take a paper plane out of transit to you and you might miss a message. The numbering technique (above) is important to know something got lost... so you can tell your friend to send another one.

 

(c) when you start to involve more friends you're gonna deal with a lot of messages.... the bigger your network, the more complex you need to design your process to deal with the massive pile of paper planes to open up and read.

 

(d) you don't need to respond to everything... sometimes you'll just get some information and it's not expected to send back a response, it's totally up to you what you want to do

 

(e) sometimes you MUST respond... hopefully this is obvious at this point.

 

(f) for everything above... "add vice versa" to the end and re-read them.

 

There are a lot of libraries that give you a lot of tools to help manage all this complexity for you, but if you don't understand what's going on under the hood it could be really challenging to write the code or make sense of all the paper planes on your floor.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×