Help needed with https put request

hi there,

I have been experimenting with node red for a while and I love it. My javascript and HTML programming skills however are rudimentary and I am thus asking for your help (or pointers).

I found a python library that allows me to interface with the web API of my EV car charger (wallbox brand).
When I run the python script on my Raspberry Pi (that also hosts my node red installation), I have no problem in locking and unlocking the car charger with the API calls. I now try to recreate that using node red's https request nodes.

With the python library as guide, I was able to get Authentication followed by "reading" values (https get requests) working fine, no problem!

However, I have not managed to "recreate" the python script put request, that e.g. locks or unlocks the car charger.

I somehow can't figure out how to "add" data (the lock / unlock command - data='{"locked":1}') to my put request.

Here is the python library excerpt that shows the put request, e.g. the lockCharger function (I don't have any documentation of the API, only script sample):
Python library

"""

Wallbox class

"""

from requests.auth import HTTPBasicAuth
import requests
import json


class Wallbox:
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.baseUrl = "https://api.wall-box.com/"
        self.jwtToken = ""
        self.headers = {
            "Accept": "application/json",
            "Content-Type": "application/json;charset=UTF-8",
        }

    def authenticate(self):
        try:
            response = requests.get(
                f"{self.baseUrl}auth/token/user",
                auth=HTTPBasicAuth(self.username, self.password),
            )
            response.raise_for_status()
        except requests.exceptions.HTTPError as err:
            raise (err)
        self.jwtToken = json.loads(response.text)["jwt"]
        self.headers["Authorization"] = f"Bearer {self.jwtToken}"

    def lockCharger(self, chargerId):
        try:
            response = requests.put(
                f"{self.baseUrl}v2/charger/{chargerId}",
                headers=self.headers,
                data='{"locked":1}',
            )
            response.raise_for_status()
        except requests.exceptions.HTTPError as err:
            raise (err)
        return json.loads(response.text)

    def setMaxChargingCurrent(self, chargerId, newMaxChargingCurrentValue):
        try:
            response = requests.put(
                f"{self.baseUrl}v2/charger/{chargerId}",
                headers=self.headers,
                data=f'{{ "maxChargingCurrent":{newMaxChargingCurrentValue}}}',
            )
            response.raise_for_status()
        except requests.exceptions.HTTPError as err:
            raise (err)
        return json.loads(response.text)

As I said, the authentication part, generating the header for the put request works fine. Here is one of the many iterations I have tried:

My sample flow:

with the https request configuration:

And my function:

var payload = msg.payload;
var topic = msg.topic;

var chargerID = global.get('chargerID') || "";
var jwt = global.get('jwt') || "";

var data = {};
var newMsg = {};

// data = {"data": [{"locked": payload}]};
data = {"locked": payload};
// data["data"].push({"chargerData":[{"locked": payload}]});

// data["locked"] = payload;

newMsg.method = "PUT";
newMsg.headers = {'Authorization': "Bearer " + jwt};
//newMsg.payload = data;
newMsg.data = {"locked": payload};
newMsg.url = "https://api.wall-box.com/v2/charger" + "/" + chargerID;

return newMsg;

And the flow:

[
    {
        "id": "84201fb6.ff6cc",
        "type": "function",
        "z": "fe4bc38e.d4da3",
        "name": "wallbox API",
        "func": "var payload = msg.payload;\nvar topic = msg.topic;\n\nvar chargerID = global.get('chargerID') || \"\";\nvar jwt = global.get('jwt') || \"\";\n\nvar data = {};\nvar newMsg = {};\n\n// data = {\"data\": [{\"locked\": payload}]};\ndata = {\"locked\": payload};\n// data[\"data\"].push({\"chargerData\":[{\"locked\": payload}]});\n//data[\"datastreams\"].push({\"id\":\"one\", \"current_value\":\"100.00\"});\n\n// data[\"locked\"] = payload;\n\nnewMsg.method = \"PUT\";\nnewMsg.headers = {'Authorization': \"Bearer \" + jwt};\n//newMsg.payload = data;\nnewMsg.data = {\"locked\": payload};\nnewMsg.url = \"https://api.wall-box.com/v2/charger\" + \"/\" + chargerID;\n\nreturn newMsg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 377.5,
        "y": 1095,
        "wires": [
            [
                "def8a5fc.0ca618",
                "62eeaa05.e79244",
                "58ee2ce.abb36d4"
            ]
        ]
    },
    {
        "id": "f5331864.387788",
        "type": "inject",
        "z": "fe4bc38e.d4da3",
        "name": "lock",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "locked",
        "payload": "1",
        "payloadType": "num",
        "x": 179,
        "y": 1094,
        "wires": [
            [
                "84201fb6.ff6cc"
            ]
        ]
    },
    {
        "id": "8a13cc2d.4d5ae",
        "type": "debug",
        "z": "fe4bc38e.d4da3",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 811,
        "y": 1098,
        "wires": []
    },
    {
        "id": "58ee2ce.abb36d4",
        "type": "http request",
        "z": "fe4bc38e.d4da3",
        "name": "Put sample",
        "method": "use",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 560,
        "y": 1100,
        "wires": [
            [
                "8a13cc2d.4d5ae"
            ]
        ]
    },
    {
        "id": "def8a5fc.0ca618",
        "type": "debug",
        "z": "fe4bc38e.d4da3",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 542,
        "y": 1053,
        "wires": []
    },
    {
        "id": "9bcdd543.5dab18",
        "type": "inject",
        "z": "fe4bc38e.d4da3",
        "name": "unlock",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "locked",
        "payload": "0",
        "payloadType": "num",
        "x": 179,
        "y": 1136,
        "wires": [
            [
                "84201fb6.ff6cc"
            ]
        ]
    },
    {
        "id": "62eeaa05.e79244",
        "type": "json",
        "z": "fe4bc38e.d4da3",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 507,
        "y": 1151,
        "wires": [
            [
                "5318996e.6b3c18"
            ]
        ]
    },
    {
        "id": "5318996e.6b3c18",
        "type": "debug",
        "z": "fe4bc38e.d4da3",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 646,
        "y": 1145,
        "wires": []
    }
]

I have tried adding the "data" to msg.payload, msg.data, msg.payload.data etc. but it just does not seem to work ... in everyone of these instances, I get a statusCode = 200 reply with the complete car charger status information but the locked state does not change ...

What have I missed!?

THANKS

It should be newMsg.payload = {"locked": payload} not newMsg.data = ...

And it looks like you haven't set the Content-Type in the headers either

newMsg.headers = {
   'Authorization': "Bearer " + jwt,
   'Content-Type': 'application/json'
};
1 Like

thanks @hardilb, I have tried that as well as one of the many variations of my function!
But I guess your reply confirms that the msg.payload should be passed on to the https put request, right?

Ahh .... I just tried it again, and while I was writing my reply, the web interface suddenly showed "unlocked"!

I THINK I WAS JUST TOO IMPATIENT! It just took a while for the system to "respond" ...!?

Thanks for confirming!

1 Like