I made a script with the help of our AI friends. I just updated it with the new API-mess-ups by Wallbox… For me it works fine. It’s not the most versatile script, but it reflects the right statusses (charging, connected,…) and you’re able to set the Amps and start or stop charging.
You need to run it with an argument via a flow. Possible arguments are ‘status’, ‘start’, ‘stop’, ‘set 6’ & ‘set 10’.
If you need anything extra (like set 16), I think the script will be easily adaptible.
I run the status every 3 minutes and set/start/stop whenever necessary. Running the script more often will probably work, but you will also run into temporary blockings from the API…
// === WALLBOX PULSAR PLUS - HOMEYSCRIPT (bijgewerkt juni 2026) ===
const username = 'login'; // myWallbox e-mail
const password = 'password'; // wijzig dit naar je nieuwe wachtwoord!
const MYCHARGERID = chargerid;
const API_BASE = "https://api.wall-box.com/";
const URL_GROUPS = 'v3/chargers/groups';
const URL_REMOTE = `v3/chargers/${MYCHARGERID}/remote-action`;
const URL_SET_CURRENT = `v2/charger/${MYCHARGERID}`;
function toBase64(str) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let output = '';
let i = 0;
str = unescape(encodeURIComponent(str));
while (i < str.length) {
const a = str.charCodeAt(i++);
const b = str.charCodeAt(i++);
const c = str.charCodeAt(i++);
const triplet = (a << 16) | (isNaN(b) ? 0 : b << 8) | (isNaN(c) ? 0 : c);
output += chars.charAt((triplet >> 18) & 63) +
chars.charAt((triplet >> 12) & 63) +
(isNaN(b) ? '=' : chars.charAt((triplet >> 6) & 63)) +
(isNaN(c) ? '=' : chars.charAt(triplet & 63));
}
return output;
}
async function getToken() {
const auth = Buffer.from(username + ":" + password).toString("base64");
const response = await fetch("https://user-api.wall-box.com/users/signin", {
method: "GET",
headers: {
"Authorization": "Basic " + auth,
"Partner": "wallbox",
"Accept": "application/json"
}
});
const raw = await response.text();
let data;
try {
data = JSON.parse(raw);
} catch (e) {
throw new Error("Login is not JSON: " + raw);
}
if (
!data.data ||
!data.data.attributes ||
!data.data.attributes.token
) {
throw new Error("No token received: " + raw);
}
return data.data.attributes.token;
}
async function getStatus(token) {
const response = await fetch(API_BASE + URL_GROUPS, {
method: 'GET',
headers: { 'Authorization': 'Bearer ' + token, 'Accept': 'application/json' }
});
if (!response.ok) {
const err = 'Groups fout: HTTP ' + response.status;
console.log(err);
await tag('Wallbox_error', err);
throw new Error(err);
}
const data = await response.json();
let found = false;
let chargerStatus = {
status: 0,
chargingPower: 0,
maxChargingCurrent: 0,
addedEnergy: 0,
locked: false,
online: false,
isCharging: false,
carConnected: false
};
if (data.result && data.result.groups) {
for (const group of data.result.groups) {
if (group.chargers) {
for (const ch of group.chargers) {
if (ch.id === MYCHARGERID) {
found = true;
const statusCode = ch.status || 0;
const isOnline = statusCode !== 0;
// Alleen werkelijk laden als er effectief vermogen loopt
const isCharging = (ch.chargingPower || 0) > 100;
// Auto verbonden?
const carConnected = statusCode !== 161;
chargerStatus = {
status: statusCode,
chargingPower: ch.chargingPower || 0,
maxChargingCurrent: ch.maxChargingCurrent || 0,
addedEnergy: ch.addedEnergy || 0,
locked: ch.locked === 1,
online: isOnline,
isCharging: isCharging,
carConnected: carConnected
};
break;
}
}
}
}
}
if (!found) {
const err = 'Charger niet gevonden in groups';
console.log(err);
await tag('Wallbox_error', err);
throw new Error(err);
}
return chargerStatus;
}
async function startCharging(token) {
const response = await fetch(API_BASE + URL_REMOTE, {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 1 })
});
if (!response.ok) {
const err = 'Start fout: HTTP ' + response.status;
console.log(err);
await tag('Wallbox_error', err);
throw new Error(err);
}
}
async function stopCharging(token) {
const response = await fetch(API_BASE + URL_REMOTE, {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 2 })
});
if (!response.ok) {
const err = 'Stop fout: HTTP ' + response.status;
console.log(err);
await tag('Wallbox_error', err);
throw new Error(err);
}
}
async function setAmps(token, amps) {
if (amps < 6 || amps > 32) {
const err = 'Amps moet tussen 6 en 32 liggen';
console.log(err);
await tag('Wallbox_error', err);
throw new Error(err);
}
const response = await fetch(API_BASE + URL_SET_CURRENT, {
method: 'PUT',
headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
body: JSON.stringify({ maxChargingCurrent: amps })
});
if (!response.ok) {
const err = 'Set amps fout: HTTP ' + response.status;
console.log(err);
await tag('Wallbox_error', err);
throw new Error(err);
}
}
if (!args || args.length === 0 || typeof args[0] !== 'string') {
const err = 'Geef een argument: status | start | stop | set 6 | set 10';
console.log(err);
await tag('Wallbox_error', err);
throw new Error(err);
}
const arg = args[0].trim().toLowerCase();
try {
const token = await getToken();
if (arg === 'status') {
const status = await getStatus(token);
await tag('Wallbox_status', status.status);
await tag('Wallbox_chargingPower', status.chargingPower);
await tag('Wallbox_maxCurrent', status.maxChargingCurrent);
await tag('Wallbox_addedEnergy', status.addedEnergy);
await tag('Wallbox_locked', status.locked ? 'true' : 'false');
await tag('Wallbox_online', status.online ? 'true' : 'false');
await tag('Wallbox_isCharging', status.isCharging ? 'true' : 'false');
await tag('Wallbox_carConnected', status.carConnected ? 'true' : 'false');
await tag('Wallbox_lastUpdate', new Date().toLocaleString());
await tag('Wallbox_error', '');
console.log('Status tags aangemaakt:', status);
return 'Status opgehaald en tags gezet';
} else if (arg === 'start') {
await startCharging(token);
await tag('Wallbox_lastAction', 'Gestart');
await tag('Wallbox_error', '');
return 'Gestart';
} else if (arg === 'stop') {
await stopCharging(token);
await tag('Wallbox_lastAction', 'Gestopt');
await tag('Wallbox_error', '');
return 'Gestopt';
} else if (arg.startsWith('set ')) {
const ampsStr = arg.split(' ')[1];
const amps = parseInt(ampsStr, 10);
if (isNaN(amps)) throw new Error('Ongeldig amps: ' + ampsStr);
await setAmps(token, amps);
await tag('Wallbox_lastAction', `Set ${amps}A`);
await tag('Wallbox_maxCurrent', amps);
await tag('Wallbox_error', '');
return `Set ${amps}A`;
} else {
throw new Error('Ongeldig argument: ' + arg);
}
} catch (err) {
console.log('Hoofdfout:', err.message);
await tag('Wallbox_error', err.message);
throw err;
}
@Arne_Sch @peav @Henrik_Oscarsson