# How to use OCPP in Node-Red

**URL:** https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495
**Category:** General
**Tags:** function-node
**Created:** [18 February 2025 19:07 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495 "2025-02-18T19:07:07Z")
**Posts on this page:** 14
**Page:** 3

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [12 May 2025 09:36 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/43 "2025-05-12T09:36:22Z")

</div>

> [@nygma2004](#):
>
> ```auto
> 12 May 08:03:40 - [info] [server response:06247e5e01a10f5c] ERROR: missing msgId for return target
> 12 May 08:03:40 - [info] [server response:06247e5e01a10f5c] ERROR: missing msgId for return target
> 12 May 08:03:40 - [info] [server response:06247e5e01a10f5c] ERROR: missing msgId for return target
> 
> ```

Search for id `06247e5e01a10f5c` and use debug nodes set to show full message to see why/where these kind of messages are coming from (NOTE: my flows dont have that ID)

> [@nygma2004](#):
>
> checking or unchecking OCPP 1.6 SOAP option in the CS server node which seems to restart the server.

Depending on what you modify and what deploy mode you use in node-red, connections and other entities will be destroyed and recreated. This is normal.

> [@nygma2004](#):
>
> > [@Steve-Mcl](#):
> >
> > Are you seeing the `BootNotification` ever?
> 
> I don't think I have responded to your question. I think I have seen the BootNotification a long time ago when I first deployed this code. But when I re-deploy the flow, I don't see it.

That will depend on deploy mode and/or what you are changing in flows before you hit deploy.

---

<div class="post-metadata">

### Author: ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)
#### Post date: [12 May 2025 18:30 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/44 "2025-05-12T18:30:42Z")

</div>

It looks like I found the issue with the missing msgid. I implemented the same logic as catching the `ONLINE` and `OFFLINE ` messages with a function node, just did it slighly differently. It was missing setting the `msg.msgId` property. Now it is fixed:

```auto
if (msg.ocpp.websocket === "ONLINE") {
    msg.payload = { "command" : "OnlineNotification", "data": {} };
    msg.ocpp.command = "OnlineNotification";
    msg.msgId = msg._msgid;
}

if (msg.ocpp.websocket === "OFFLINE") {
    msg.payload = { "command": "OfflineNotification", "data": {} };
    msg.ocpp.command = "OfflineNotification";
    msg.msgId = msg._msgid;
}

```

And in the switch node it is wired into the Generic Status=Accepted route.

But this did not change the end result. I still getting the OFFLINE message after some time (after 14 seconds). So it looks like I am still missing something.  
And it also looks like the response to the `OFFLINE` message fails (shows `message failed` on the sender node), but the Heartbeats are still coming after 2 minutes.

I could be doing something different from your flow, I just can't see the difference. I try to disable my flow, import yours and see if that makes a difference.  
If not, I guess there is something special about this particular CP.

---

<div class="post-metadata">

### Author: ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)
#### Post date: [12 May 2025 19:21 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/45 "2025-05-12T19:21:14Z")

</div>

OK, Steve's flow is working. I am not getting the offline messages. I have to admit, I am still not sure what is the difference, why my flow was not working. I also started from the same sample flow, and I have not taken anything off of it. And as far as I can see, Steve's flow does nothing with the ONLINE and OFFLINE messages, just goes to logging.

Let me ask a few question to make sure I understand this flow correctly:

- what is the purpose of the function node between the CS request and the command switch. My understanding is that it is mainly preparing the data for logging, but does not really influence the request-response communication. What is the real purpose of the `msg.ocppData` object besides logging?
- @Paul-Reed can you send a sample data that you send as a charging profile? Are you keep changing profile 0?

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [13 May 2025 13:23 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/46 "2025-05-13T13:23:03Z")

</div>

> [@nygma2004](#):
>
> can you send a sample data that you send as a charging profile?

@nygma2004 - I'll be charging my car tomorrow, so I'll grab the profiles and post them here.

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [14 May 2025 12:11 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/47 "2025-05-14T12:11:57Z")

</div>

@nygma2004 - Here is the charging profile for Steve's flow, which charges at maximum possible;

```auto
{
    "_msgid": "d7e2b9164bbbdff0",
        "topic": "RemoteStartTransaction",
            "payload": {
        "command": "RemoteStartTransaction",
            "data": {
            "connectorId": 1,
                "timestamp": "2025-05-14T11:49:39.079Z",
                    "idTag": "MYTAG",
                        "meterStart": 0
        }
    }
}

```

And this is the profile that I use to charge at a variable current (to match my solar surplus).  
The initial profile sent to the charger sets the `chargingProfilePurpose` to the `TxDefaultProfile`

```auto
{
  "_msgid": "ba259d12d2062aa3",
  "payload": {
    "command": "SetChargingProfile",
    "data": {
      "connectorId": 1,
      "csChargingProfiles": {
        "chargingProfileId": 1,
        "transactionId": 69357,
        "stackLevel": 0,
        "chargingProfilePurpose": "TxDefaultProfile",
        "chargingProfileKind": "Relative",
        "chargingSchedule": {
          "chargingRateUnit": "A",
          "chargingSchedulePeriod": [
            {
              "startPeriod": 0,
              "limit": 32,
              "numberPhases": 1
            }
          ]
        }
      }
    }
  },
  "topic": "SetChargingProfile",
  "_event": "node:2ee04367c8ee7e11"
}

```

...and all of the subsequent 15 second updated profiles changes the `limit` amount and also the `chargingProfilePurpose` to `TxProfile`. This is to avoid the charger running through it's initialization each time I send a new profile, so the charging rate continues smoothly.

```auto
{
  "_msgid": "ba259d12d2062aa3",
  "payload": {
    "command": "SetChargingProfile",
    "data": {
      "connectorId": 1,
      "csChargingProfiles": {
        "chargingProfileId": 1,
        "transactionId": 69357,
        "stackLevel": 0,
        "chargingProfilePurpose": "TxProfile",
        "chargingProfileKind": "Relative",
        "chargingSchedule": {
          "chargingRateUnit": "A",
          "chargingSchedulePeriod": [
            {
              "startPeriod": 0,
              "limit": 12,
              "numberPhases": 1
            }
          ]
        }
      }
    }
  },
  "topic": "SetChargingProfile",
  "_event": "node:2ee04367c8ee7e11"
}

```

Note also that a session `transactionId` is required before submitting the profiles otherwise it will fail.  
It's obtained by running a `RemoteStartTransaction` first (posted above), which generates the transaction ID, which is saved to context.  
I allow 20 seconds (as it doesn't arrive quickly!) using a delay node, then populate the profile by getting it from context thereafter.

 ![charger profile flowchart](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/1/416ff93879cc83bd6b81fe38106ce557a49b370d.png)

---

<div class="post-metadata">

### Author: ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)
#### Post date: [15 May 2025 05:45 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/48 "2025-05-15T05:45:12Z")

</div>

Thanks. So far I configured the `RemoteStartTransaction` to be issued once the `Preparing` StatusNotification is received. The guys are at holiday right now, so I had no change to test it yet.  
But now I understand why the `transactionId` is required, because I don't see that being sent when you start the charging manually.

---

<div class="post-metadata">

### Author: ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)
#### Post date: [20 May 2025 21:11 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/49 "2025-05-20T21:11:29Z")

</div>

> [@Paul-Reed](#):
>
> `TxProfile`

Thanks for the details. I only had time to play around with it today. So far only triggering this manually for testing.

The charging is in progress now, and I get the transaction id from the MeterValues messages which is now 34844. With the two inject nodes I send in a TxDefaultProfile and later a TxProfile and also make sure that I inject the proper transaction ID. In both cases te response shows that it is accepted, but I am not seeing any change in the charging speed.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/6/760e428a541bb364e5ab469781aa081ebeb049bb.png)

The only change I made is to set the limit to 16A on all 3 phases (as this is a 3 phase CP):

```auto
            "chargingSchedule": {
                "chargingRateUnit": "A",
                "chargingSchedulePeriod": [
                    {
                        "startPeriod": 0,
                        "limit": 16,
                        "numberPhases": 3
                    }
                ]
            }

```

The only thing I can see that this charging session was started manually, not my RemoteStartTransaction. But that should not make a difference, right?

I also found this site which explains the different profiles: [How to use smart charging with OCPP 1.6J](https://www.ampcontrol.io/ocpp-guide/how-to-use-smart-charging-with-ocpp)

Here it menions the Maximum Profile:

```auto
{
    "command": "SetChargingProfile",
    "data": {
        "connectorId": 0,
        "csChargingProfiles": {
            "chargingProfileId": 1,
            "stackLevel": 0,
            "chargingProfilePurpose": "ChargePointMaxProfile",
            "chargingProfileKind": "Relative",
            "chargingSchedule": {
                "chargingRateUnit": "A",
                "chargingSchedulePeriod": [
                    {
                        "startPeriod": 0,
                        "limit": 16,
                        "numberPhases": 3
                    }
                ]
            }
        }
    }
}

```

I though maybe there is a default 10A limit in this charger, which is overwriting the 16A given for the TxProfile. But it does absolutely nothing for me. The charger accepts all chargning profiles but the charge level remains 10A on each phase. Btw, the `ChargePointMaxProfile` needs to be sent to `connectorId: 0` and does not need a `transactionId`.

I also thought that maybe the charger has some other profiles in higher `stackLevel`. Therefore I also tried clearing the profiles:

```auto
{
    "command": "ClearChargingProfile",
    "data": {
        "connectorId": 0,
        "chargingProfilePurpose": "ChargePointMaxProfile"
    }
}

```

Interestingly, the CP only accpeted clearing the MaxProfile and not the Tx profiles. For those it sent an unknown command. But regardless there is no change in the charging speed, it remains 3x10A.  
I am starting considering that the OCPP implementation in these chargers is a bit buggy.

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [20 May 2025 21:37 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/50 "2025-05-20T21:37:38Z")

</div>

I'm not familiar with 3 phase... but...

> [@nygma2004](#):
>
> ```auto
> {
> "command": "ClearChargingProfile",
> "data": {
> "connectorId": 0,
> "chargingProfilePurpose": "ChargePointMaxProfile"
> }
> }
> 
> ```

Try

```auto
{
    "command": "ClearChargingProfile",
    "data": {
        "connectorId": 0,
        "chargingProfilePurpose": "TxProfile"
    }
}

```

---

<div class="post-metadata">

### Author: ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)
#### Post date: [20 May 2025 21:57 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/51 "2025-05-20T21:57:28Z")

</div>

Yes, I did and I get `unknown` as a response.

But I just realized `ChargePointMaxProfile` needs to be sent to `connectorId: 0` as this applies to the entire CP, `TxProfile` needs to go to the actual connector. Therefore the command maybe should be sent to connector 1:

```auto
{
    "command": "ClearChargingProfile",
    "data": {
        "connectorId": 1,
        "chargingProfilePurpose": "TxProfile"
    }
}

```

I will try tomorrow, getting late for me.

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [21 May 2025 08:39 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/52 "2025-05-21T08:39:18Z")

</div>

> [@nygma2004](#):
>
> Therefore the command maybe should be sent to connector 1:

Yes, connector 1 works for me.

Although I never need to clear the profile as I'm constantly overwriting it using `chargingProfilePurpose: TXProfile` in the charging profile itself.  
I use that because it gives me control over the charging limit, so I can change it without ending the current session.  
For example, if there isn't much 'free' solar power, the flow will drop the charging rate accordingly.

---

<div class="post-metadata">

### Author: ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)
#### Post date: [4 June 2025 05:55 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/53 "2025-06-04T05:55:19Z")

</div>

Just an update: it is still not working, I raised a service request with the manufacturer. Let's see if there is a trick with this CP I am not aware of.

---

<div class="post-metadata">

### Author: ![automatikas](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/automatikas/32/101614_2.png) [@automatikas](https://discourse.nodered.org/u/automatikas)
#### Post date: [27 June 2025 12:30 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/54 "2025-06-27T12:30:33Z")

</div>

> [@Paul-Reed](#):
>
> And this is the profile that I use to charge at a variable current (to match my solar surplus).  
> The initial profile sent to the charger sets the `chargingProfilePurpose` to the `TxDefaultProfile`

I send `TxDefaultProfile` with `"limit": 0` so when I start charging session, it stops CP from starting imediatly charging and lets NR to start "looping", or me to take dessition.

@Paul-Reed can you share how your `Control Rate` works? Do you use any other Dinamic limits like: max CB rating, EV charge % limit?

I have ABB Terra 22kW CP that pauses charging when profile limit is set under 6A. This give some notification spam on EV app on a cloudy day when PV goes on rollercouster.

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [28 June 2025 10:25 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/55 "2025-06-28T10:25:41Z")

</div>

> [@automatikas](#):
>
> @Paul-Reed can you share how your `Control Rate` works?

> [@automatikas](#):
>
> I send `TxDefaultProfile` with `"limit": 0` so when I start charging session, it stops CP from starting imediatly charging and lets NR to start "looping"

I do something very similar.

 ![charger screenshot](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/2/022cc8275ce8a80a3d88a8a7de6bada372ce9222.png)

The red group sets up and runs the initial TxDefaultProfile, and starts the 15 second loop.  
Once the loop is running, the charging limit is set by the 'Control Rate' function node, which, depending upon data stored in the global context, sets the charging limit for the following 15 seconds.  
The global context contains grid voltage, grid power (inflow/outflow) and data from/to the dashboard.  
The 'Auto' mode uses only surplus solar energy, which is slow, but ok for top ups, but hey, it's free!  
The preset limits helps me maximise solar, and still charge at a reasonable rate, so for example if I set 24A limit, I can offset the charging costs by up to 50% (50% solar + 50% consumption).

![phone](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/f/ffb61e0e4144d462c54f6ee59cd3a85843cf6a7e.gif)

The dashboard is still being constructed, as I've switched to UIbuilder.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [26 September 2025 10:26 UTC](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495/56 "2025-09-26T10:26:28Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://discourse.nodered.org/t/how-to-use-ocpp-in-node-red/95495.md?page=2)
